2019.8.4考试记录

8.4日考试记录

今天题量挺大,没有在考试的时候写记录

而且做得也挺烂,所以仔细写一下记录



其实挺水一题。

其实我以前见过这道题目,做的时候直接开了个十六维数组233。

这道题的灵魂就是十六位的二进制。

但是考后随便动了动脑子,发现我恐怕是傻的真的菜

很明显,这个题目的操作就是按位异或,所以根本不需要花里胡哨乱七八糟的转变操作,

直接按环后移以为,异或一下就能够得出下一个状态

而因为只要出现循环,就会一直按照一个循环节绕下去,所以只要找循环节就OK了

然后我是真的服了我自己

根本没动脑子,以为循环节一定会包括第一个状态…

我现在真的不知道我当时到底什么状态犯这种错误

所以卡了我一个小时???

彻底重构代码三次???

其实第二题我也出现了这种问题,说明本次考试之中,我做题的思考太少了。

Think Twice,Code Once\color{red}\text{Think Twice,Code Once}Think Twice,Code Once

真理好吧

我喷我自己

Code:

#include<bits/stdc++.h>	
using namespace std;
long long n,b,i,j,f[51][1<<16],a,cf=0;
int main(){
    scanf("%lld%lld",&n,&b);
    for (i=0;i<1<<n;i++)
    	for (j=0;j<n;j++)
    		f[0][i]+=((i&1<<(j+1)%n)>0^(i&1<<j)>0)*(1<<j);
    for (i=1;i<=50;i++)
    	for (j=0;j<1<<n;j++)
    		f[i][j]=f[i-1][f[i-1][j]];
    for (i=1;i<=n;i++){
        scanf("%d",&a);
        cf=cf<<1|a;
    }
    for(i=50;i>=0;i--)
    	if(1LL<<i<=b){
    	    b-=1LL<<i;
    	    cf=f[i][cf];
    	}
    for (i=n-1;i>=0;i--)
    	printf("%lld\n",(cf&1<<i)>0);
    return 0;
}


也不是很难的

但是也把我卡了很久,原因上面说了

一个很纯粹的模拟和离散化。

没有对头的咩咩不干扰答案,所以只要按照有对头咩咩的位置一个一个处理,用一个set判断就可以了

所以我还重构了一次代码???

真的是蠢哭了我去

Code:

#include<bits/stdc++.h>
using namespace std;
const int MAXK=1050;
int n,k,a,b,ans;
set <int> s;
struct node{
	int sheep;
	vector<int>hate; 
}unfr[MAXK*2];
bool cmp(node x,node y){
	return x.sheep<y.sheep;
}
int main(){
    freopen("photo.in","r",stdin);
    freopen("photo.out","w",stdout);
	scanf("%d%d",&n,&k);
	for(int i=0;i<k;i++){
		scanf("%d%d",&a,&b);
		unfr[i].sheep=min(a,b);
		unfr[i].hate.push_back(max(a,b));
		unfr[i+k].sheep=max(a,b);
	}
	sort(unfr,unfr+2*k,cmp);
	for(int i=0;i<2*k;i++){
		int siz=unfr[i].hate.size();
		if(s.count(unfr[i].sheep))
			ans++,s.clear();
		for(int j=0;j<siz;j++)
			s.insert(unfr[i].hate[j]);
	}
	printf("%d",ans+1);
	return 0;
}



看起来好像就是一道裸的最短路

然后真的是的233

Dijkstra模板就过了

于是我还是没拿分???

本人Dijksta+heap优化,然后本地跑过。

测试…

Complie Error????

lock居然也是Bits的保留字我是真的…

心里一句MMP

将lock改了之后,测了还是没a

发现lock的位置又摆错了233

注意啊!!!

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1005;
int n,t,a,b,c,d[MAXN],loc[MAXN];
struct edge{
	int from,to,value;
	bool operator <(const edge &b) const{
		return value>b.value;
	} 
}tmp,tmp233;
vector <edge> q[MAXN];
priority_queue <edge> Q;
void dijkstra(){
	memset(d,0x3f,sizeof(d));
	tmp.from=0,tmp.to=1,tmp.value=0;
	Q.push(tmp),d[1]=0;
	while(!Q.empty()){
		tmp=Q.top(),Q.pop();
		if(loc[tmp.to]) continue;
		loc[tmp.to]=1;
		int siz=q[tmp.to].size();
		for(int i=0;i<siz;i++)
			if(d[q[tmp.to][i].to]>d[tmp.to]+q[tmp.to][i].value){
				tmp233=q[tmp.to][i];
				d[q[tmp.to][i].to]=d[tmp.to]+q[tmp.to][i].value;
				tmp233.value=d[q[tmp.to][i].to];
				Q.push(tmp233);
			}
	}
}
int main(){
    freopen("gohome.in","r",stdin);
    freopen("gohome.out","w",stdout);
	scanf("%d%d",&t,&n);
	for(int i=0;i<t;i++){
		scanf("%d%d%d",&a,&b,&c);
		tmp.from=a,tmp.to=b,tmp.value=c;
		q[a].push_back(tmp);
		tmp.from=b,tmp.to=a;
		q[b].push_back(tmp);
	}
	dijkstra();
	printf("%d",d[n]);
	return 0;
}



属于一道超出NOIP的难题(黑题233)

正解给的是状压DP,然后也写出了暴力搜索的优化方法作为标程。
Code(DP):

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define NMAX 12
#define infinite 1000000000
int dp[1 << NMAX];
int main() {
	freopen("haywire.in","r",stdin);
	freopen("haywire.out","w",stdout);
	int n;
	scanf("%d", &n);
	int nbr[13][3];
	for (int i = 0; i < n; i++) {
		scanf("%d %d %d", &nbr[i][0], &nbr[i][1], &nbr[i][2]);
		nbr[i][0]--;	nbr[i][1]--;	nbr[i][2]--;
	}
	dp[0] = 0;
	for (int subset = 1; subset < (1 << n); subset++) {
		int pending_links = 0;
		for (int i = 0; i < n; i++) {//计算链出去的线 
			if (subset & (1<<i)) {
				pending_links += 3-(((subset >> nbr[i][0]) & 1) +
				                 ((subset >> nbr[i][1]) & 1) +
				                 ((subset >> nbr[i][2]) & 1));
			}
		}
		dp[subset] = infinite;
		for (int i = 0; i < n; i++) {
			if (subset & (1 << i)) {
				int cost = pending_links - 3 + 2 * (((subset >> nbr[i][0]) & 1) +
				                           ((subset >> nbr[i][1]) & 1) +
				                           ((subset >>  nbr[i][2]) & 1));
				dp[subset] = min(dp[subset], dp[subset & ~(1<<i)] + cost);
			}
		}
	}
	printf("%d\n", dp[(1 << n) - 1]);
}

Code(暴力优化):

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define NMAX 12
#define infinite 1000000000
int dp[1 << NMAX];
int main() {
	freopen("haywire.in","r",stdin);
	freopen("haywire.out","w",stdout);
	int n;
	scanf("%d", &n);
	int nbr[13][3];
	for (int i = 0; i < n; i++) {
		scanf("%d %d %d", &nbr[i][0], &nbr[i][1], &nbr[i][2]);
		nbr[i][0]--;	nbr[i][1]--;	nbr[i][2]--;
	}
	dp[0] = 0;
	for (int subset = 1; subset < (1 << n); subset++) {
		int pending_links = 0;
		for (int i = 0; i < n; i++) {//计算链出去的线 
			if (subset & (1<<i)) {
				pending_links += 3-(((subset >> nbr[i][0]) & 1) +
				                 ((subset >> nbr[i][1]) & 1) +
				                 ((subset >> nbr[i][2]) & 1));
			}
		}
		dp[subset] = infinite;
		for (int i = 0; i < n; i++) {
			if (subset & (1 << i)) {
				int cost = pending_links - 3 + 2 * (((subset >> nbr[i][0]) & 1) +
				                           ((subset >> nbr[i][1]) & 1) +
				                           ((subset >>  nbr[i][2]) & 1));
				dp[subset] = min(dp[subset], dp[subset & ~(1<<i)] + cost);
			}
		}
	}
	printf("%d\n", dp[(1 << n) - 1]);
}

代码很长很长很长很长

我也不能完全理解233,只能按照自己去的梳理一下

由于这是一个排列类问题,所以直接来说本身并不很好转化为集合问题

但是发现:如果将确定了的兔子看做一个集合,那么这个集合往外延伸而耗费的电线其实和集合内的兔兔顺序无关

这就可以压缩成一个状态。

状态的设定呢?

也就是用01串表示这个兔子有没有在之前选过的这个集合里面
如果要往前推进,那么就要把下个兔兔放入集合中,这时就会有三个电线来源,一个是集合内的兔子连上新加入的,和没有连上但是需要延长的,还有就是加入的兔兔自己还要往外延的。

于是转移就是在加兔兔的时候,当前状态的集合删去一个兔兔的状态。加上一个电线数。

差不多就是这样

而暴力并不比dp容易理解一些,所以也不做赘述

主要是难得码字了233

但是确实,实现起来需要沉下心来想很久,现在也已经要下晚自习了,所以并不打算手打一遍


这次考试实在是考的瓜皮出一种境界了

仔细反省,码字之前的思考是真的不够缜密

但是其实平时的话我并不会这样,这两天考试的心态都有点过于急切了。

也有可能是没休息好没能静下心来吧

反正这都是问题,其实在算法层面,这些题目真的都没有什么可以说的,但是就是实现的时候写出的bug,映射了我自己打代码的时候的过于急躁

Calm down.\color{red}\text{Calm down.}Calm down.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值