POJ训练记录5
3074.Sudoku
数独。。dancing link经典题
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | #include<map> #include<set> #include<cmath> #include<ctime> #include<queue> #include<cstdio> #include<vector> #include<bitset> #include<cstring> #include<iostream> #include<algorithm> #define inf 1000000000 #define ll long long #define pa pair<ll,int> #define rp(x,y) x*9+y+81 #define cp(x,y) x*9+y+162 #define pp(x,y) x*9+y+243 using namespace std; char ch[105]; int id,tot,ans[105]; int L[300005],R[300005],u[300005],d[300005]; int h[1005],C[300005],X[300005],s[1005]; bool mark[1005],mp[1005][1005]; struct data{ 	int pos,val; }a[300005],q[105]; void del(int c) { 	L[R[c]]=L[c];R[L[c]]=R[c]; 	for(int i=d[c];i!=c;i=d[i]) 	{ 		for(int j=R[i];j!=i;j=R[j]) 			u[d[j]]=u[j],d[u[j]]=d[j],s[C[j]]--; 	} } void add(int c) { 	L[R[c]]=R[L[c]]=c; 	for(int i=u[c];i!=c;i=u[i]) 		for(int j=L[i];j!=i;j=L[j]) 			u[d[j]]=d[u[j]]=j,s[C[j]]++; } void link(int r,int c) { 	s[c]++;C[++tot]=c;X[tot]=r; 	u[tot]=c;d[tot]=d[c]; 	u[d[tot]]=tot;d[u[tot]]=tot; 	if(h[r]==-1) 		h[r]=L[tot]=R[tot]=tot; 	else 	{ 		L[tot]=h[r];R[tot]=R[h[r]]; 		L[R[tot]]=tot;R[L[tot]]=tot; 	} } bool dance(int k) { 	if(R[0]==0) 	{ 		for(int i=1;i<=81;i++) 			ans[q[i].pos]=q[i].val; 		for(int i=1;i<=81;i++)printf("%d",ans[i]); 		return 1; 	} 	int mn=inf,c=R[0][;; 	for(int i=R[0];i;i=R[i]) 		if(s[i]<mn)mn=s[i],c=i; 	del(c); 	for(int i=d[c];i!=c;i=d[i]) 	{ 		q[k+1]=a[X[i]]; 		for(int j=R[i];j!=i;j=R[j])del(C[j]); 		if(dance(k+1))return 1; 		for(int j=L[i];j!=i;j=L[j])add(C[j]); 	} 	add(c); 	return 0; } int main() { 	while(scanf("%s",ch+1)) 	{ 		if(ch[1]=='e')return 0; 		id=tot=0; 		memset(h,-1,sizeof(h)); 		memset(mark,0,sizeof(mark)); 		for(int i=0;i<=4*81;i++) 		{ 			L[i+1]=i,R[i]=i+1; 			u[i]=d[i]=i;s[i]=0; 		} 		L[0]=4*81;R[4*81]=0;tot=4*81; 		for(int i=0;i<9;i++) 			for(int j=0;j<9;j++) 				if(ch[i*9+j+1]!='.') 				{ 					int t=ch[i*9+j+1]-'0',p=i/3*3+j/3; 					mark[rp(i,t)]=mark[cp(j,t)]=mark[pp(p,t)]=1; 				} 		for(int i=0;i<9;i++) 			for(int j=0;j<9;j++) 			{ 				int t=ch[i*9+j+1]-'0',p=i/3*3+j/3; 				if(ch[i*9+j+1]=='.')t=0; 				if(t!=0) 				{ 					id++;a[id].pos=i*9+j+1;a[id].val=t; 					link(id,i*9+j+1); 					link(id,rp(i,t)); 					link(id,cp(j,t)); 					link(id,pp(p,t));					 				} 				else  					for(int t=1;t<=9;t++) 						if(!mark[rp(i,t)]&&!mark[cp(j,t)]&&!mark[pp(p,t)]) 						{ 							id++;a[id].pos=i*9+j+1;a[id].val=t; 							link(id,i*9+j+1); 							link(id,rp(i,t)); 							link(id,cp(j,t)); 							link(id,pp(p,t));												 						} 			} 			dance(0); 			puts(""); 	} 	return 0; } | 
3252.Round Numbers
简单数位dp
f(i,j,x,y)表示最高的i位,0比1多j个,是否已小于n,高位是否有1
然后转移显然。。。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #include<map> #include<set> #include<cmath> #include<ctime> #include<queue> #include<cstdio> #include<vector> #include<bitset> #include<cstring> #include<iostream> #include<algorithm> #define inf 1000000000 #define ll long long using namespace std; ll read() {     ll x=0,f=1;char ch=getchar();     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}     return x*f; } ll bin[40]; int a,b; int f[40][65][2][2]; int solve(ll x) { 	memset(f,0,sizeof(f)); 	f[0][30][0][0]=1; 	int t=1;while(bin[t]<=x)t++; 	for(int i=0;i<t;i++) 	{ 		int p=(bin[t-i-1]&x)>0; 		for(int j=0;j<=60;j++) 			for(int x=0;x<=1;x++) 				for(int y=0;y<=1;y++) 					if(f[i][j][x][y]) 						for(int k=0;k<=1;k++) 							if(k<=p||x==1) 								f[i+1][j+(k==0?1*y:-1)][x|(k<p)][y|(k==1)]+=f[i][j][x][y]; 	} 	int ans=0; 	for(int i=30;i<=60;i++) 		ans+=f[t][i][1][1]; 	return ans; } int main() { 	bin[0]=1;for(int i=1;i<=35;i++)bin[i]=bin[i-1]<<1; 	a=read();b=read(); 	printf("%d\n",solve(b+1)-solve(a)); 	return 0; } | 
1665.Biker’s Trip Odometer
阅读题
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include<map> #include<set> #include<cmath> #include<ctime> #include<queue> #include<cstdio> #include<vector> #include<bitset> #include<cstring> #include<iostream> #include<algorithm> #define inf 1000000000 #define ll long long #define eps 1e-7 #define pi 3.1415927 using namespace std; double d,r,T; int cas; int main() { 	while(1) 	{ 		cas++; 		scanf("%lf%lf%lf",&d,&r,&T); 		if(r==0)return 0; 		printf("Trip #%d: ",cas); 		d=d/12/5280; 		printf("%.2lf %.2lf\n",d*pi*r,d*pi*r/(T/3600)); 		if(r==0)return 0; 	} 	return 0; } | 
1930.Dead Fraction
丧心病狂。。枚举循环节
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #include<map> #include<set> #include<cmath> #include<ctime> #include<queue> #include<cstdio> #include<vector> #include<bitset> #include<cstring> #include<iostream> #include<algorithm> #define inf 1000000000 #define ll long long #define eps 1e-7 #define pi 3.1415927 using namespace std; char ch[10005]; ll ans1,ans2; ll gcd(ll a,ll b) { 	return b==0?a:gcd(b,a%b); } void solve(ll a,ll b,ll c,ll d) { 	ll t1=a*d+b*c,t2=b*d,t=gcd(t1,t2); 	t1/=t;t2/=t; 	if(t2<ans2)ans2=t2,ans1=t1; } int main() { 	while(1) 	{ 		ans2=(ll)1e60;		 		scanf("%s",ch+1); 		int n=strlen(ch+1); 		if(n==1)break; 		ll b=1,a=0; 		for(int i=3;i<=n-3;i++) 			a=a*10+ch[i]-'0',b*=10; 		ll t=b/10*9; 		for(ll i=10;i<=b;i*=10,t=t+(b/i)*9) 			solve(a/i,b/i,a%i,t); 		printf("%lld/%lld\n",ans1,ans2); 	} 	return 0; } | 
1970.The Game
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #include<map> #include<set> #include<cmath> #include<ctime> #include<queue> #include<cstdio> #include<vector> #include<bitset> #include<cstring> #include<iostream> #include<algorithm> #define inf 1000000000 #define ll long long #define eps 1e-7 #define pi 3.1415927 using namespace std; int T; int a[25][25]; int xx[]={1,1,0,-1},yy[]={0,1,1,1}; bool check(int x,int y,int k) { 	int t=a[x][y]; 	for(int i=-1;i<=5;i++) 	{ 		int nx=x+xx[k]*i,ny=y+yy[k]*i; 		if(i!=5&&i!=-1) 		{ 			if(nx<1||ny<1||nx>19||ny>19||a[nx][ny]!=t)return 0; 		} 		else  		{ 			if(nx<1||ny<1||nx>19||ny>19)continue; 			if(a[nx][ny]==t)return 0; 		} 	} 	return 1; } void solve() { 	for(int j=1;j<=19;j++) 		for(int i=1;i<=19;i++) 			if(a[i][j]!=0) 				for(int k=0;k<4;k++) 					if(check(i,j,k)) 					{ 						printf("%d\n",a[i][j]); 						printf("%d %d\n",i,j); 						return; 					} 	puts("0"); } int main() { 	scanf("%d",&T); 	while(T--) 	{ 		for(int i=1;i<=19;i++) 			for(int j=1;j<=19;j++) 				scanf("%d",&a[i][j]); 		solve(); 	} 	return 0; } | 
1185.炮兵阵地
每一行的合法放置状态只有60种
f(i,j,k)表示到第i行,前两行的状态为j,k,简单状压dp。。。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | #include<map> #include<set> #include<cmath> #include<ctime> #include<queue> #include<cstdio> #include<vector> #include<bitset> #include<cstring> #include<iostream> #include<algorithm> #define inf 1000000000 #define ll long long using namespace std; int read() { 	int x=0,f=1;char c=getchar(); 	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 	return x*f; } int n,m,top,mx; int bin[20],q[2000]; int s[105],f[105][65][65]; char a[105][15]; int cal(int x) { 	int ans=0; 	for(int i=0;i<m;i++) 		if(bin[i]&x)ans++; 	return ans; } int main() { 	bin[0]=1;for(int i=1;i<20;i++)bin[i]=bin[i-1]<<1; 	n=read();m=read(); 	for(int i=0;i<bin[m];i++) 		if((i&(i>>1))==0&&(i&(i>>2))==0)q[++top]=i; 	for(int i=1;i<=n;i++) 	{ 		scanf("%s",a[i]+1); 		for(int j=1;j<=m;j++) 			if(a[i][j]=='H')s[i]+=bin[j-1]; 	} 	for(int i=1;i<=top;i++) 		if((q[i]&s[1])==0)f[1][i][1]=cal(q[i]); 	for(int i=1;i<n;i++) 		for(int j=1;j<=top;j++) 			for(int k=1;k<=top;k++) 				if(f[i][j][k]!=-1) 					for(int x=1;x<=top;x++) 						if((q[x]&s[i+1])==0) 							if((q[j]&q[x])==0&&(q[k]&q[x])==0) 								f[i+1][x][j]=max(f[i+1][x][j],f[i][j][k]+cal(q[x])); 	for(int j=1;j<=top;j++) 		for(int k=1;k<=top;k++) 			mx=max(mx,f[n][j][k]); 	printf("%d\n",mx); 	return 0; } | 
                                  Subscribe  
                            
                                                                        
                    