赞
踩
这次考试差点挂了,1题签到题,2题dfs暴力超出时间,只能打表,3题挂了虽然做过
结果加强数据,那就玄学剪枝+打表。最终WAemmm
Time Limit: 1 Sec Memory Limit: 128 MB
奶牛按不太传统的方式玩起小朋友玩的跳房子游戏,现给出一个5*%的由数字组成的网格。它们在格子中向前前跳,向后跳,向左跳,向右跳,跳到网格中另一个数字后,又这样继续跳(可能跳到某个已跳过的数字)。一共在网格中跳过五次后,它们经过的格子数组成一个六位数(可能是0开始头的,例如000201).现问所有可以被跳出来的不同整数的总数。
输入共五行,每行五个数字.
如题
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 2 1
1 1 1 1 1
15
HINT
111111, 111112, 111121, 111211, 111212, 112111, 112121, 121111, 121112,
121211, 121212, 211111, 211121, 212111, and 212121 can be constructed.
No other values are possible.
先双重for+dfs+in+cnt++
不用担心超时问题,但要处理好边界,走过的路径用字符串存下,再用map<string,bool> 映射标记
#include<bits/stdc++.h> using namespace std; int n,cnt; char maze[10][10]; int dir[4][2]={{0,1},{1,0},{-1,0},{0,-1}}; bool in(int x,int y){ return x>=1 && x<=n && y>=1 && y<=n; } map<string,bool> vis; void dfs(int x,int y,int s,string ans){ if(s>6){ if(!vis[ans]){ vis[ans]=1; cnt++; } return ; } for(int i=0;i<4;i++){ int tx=x+dir[i][0]; int ty=y+dir[i][1]; if(in(tx,ty)){ dfs(tx,ty,s+1,ans+maze[x][y]); } } } int main(){ n=5; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cin>>maze[i][j]; } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ dfs(i,j,1,"\0"); } } while(1); cout<<cnt; return 0; }
Time Limit: 1 Sec Memory Limit: 128 MB
小Q是班长。在校运动会上,小Q班要进行队列表演。小Q要选出2*N名同学编队,每人都被编上一个号,每一个从1到N的自然数都被某2名同学佩戴,现在要求将他们排成一列,使两个编号为1的同学中间恰好夹1名同学,两个编号为2的同学中间恰好夹2名同学,……,两个编号为N的同学中间恰好夹N名同学,小Q希望知道这样的排法能否实现。
输入文件仅包括一行,即要处理的N。N<=13
输出有多少种排列顺序.
3
2
本人太蒟无法写出13和12能A的DFS,那只能打表…
dfs枚举数字1~n,for枚举格子,开个数组i+s+1 和i (s是数值),这样就可以保证s中有s个人
但有一个可行性剪枝方案
设问题的一个可行解为a1,a2,……,an,其中ai为标号为i的数字的位置,
这些数字它们对应数字的位置应该为a1+1+1,a2+2+1,……,an+n+1.这2N个整数a1,a2,……,an, a1+1+1,a2+2+1,……,an+n+1正是整数1,2,3,……,2N,因而
a1+a2+…+an+(a1+1+1)+(a2+2+1)+…+(an+n+1)=
2(a1+a2+an)+n(n+1)/2+n=2n(2n+1)/2
2(a1+a2+…+an)=(3n2-n)/2
4(a1+a2+…+an)=n(3n-1)
可见n(3n-1)应该为4的倍数,当n mod 4=0,1,2,3时,n(3n-1) mod 4分别为0,2,2,0,故n mod 4=1或2时,问题无解
#include<bits/stdc++.h> #include<windows.h> using namespace std; int n,cnt,a[50]; void dfs(int s){ if(s>n){ cnt++; return; } for(int i=1;i+s+1<=2*n;i++){ if(!a[i] && !a[i+s+1]){ a[i]=s; a[i+s+1]=s; // cout<<cnt<<endl; // for(int i=1;i<=2*n;i++){ // cout<<a[i]<<" "; // } // cout<<endl; // Sleep(2000); dfs(s+1); a[i]=0; a[i+s+1]=0; } } // cout<<cnt<<endl; // for(int i=1;i<=2*n;i++){ // cout<<a[i]<<" "; // } // cout<<endl; // Sleep(1000); } int main(){ cin>>n; if(n mod 4=1 || n mod 4=2){ cout<<0; return 0; } dfs(1); cout<<cnt; return 0; }
Time Limit: 1 Sec Memory Limit: 128 MB
给出数字P,Q,A,N,代表将分数P/Q分解成至多N个分数之和,这些分数的分子全为1,且分母的乘积不超过A。例如当输入数据为2 3 120 3时,我们可以得到以下几种分法:
本题含有多组测试数据,每组给出四个数P,Q,A,N,其中 p,q <= 800, A <= 12000,N <= 7.当输入的四个数均为0时,代表测试结束.
针对每组数据,输出共有多少种不同的分法。
2 3 120 3
2 3 300 3
2 3 299 3
2 3 12 3
2 3 12000 7
54 795 12000 7
2 3 300 1
2 1 200 5
2 4 54 2
0 0 0 0
4
7
6
2
42
1
0
9
3
老师讲过的题本蒟蒻居然wa了emmm
暴力枚举每个分母
a/b+c/d=ac+bc/bd(两个分数向加,分子分母公式)
ab=dc(两个分数相等,分子分母公式)
再加些极大化,可行性剪枝
#include<bits/stdc++.h> using namespace std; int a,cnt; void dfs(int p,int q,int nex,int x,int t){ if(nex<=a && !p){ cnt++; return; } if(nex*x>a){ return; } if(!t){ return; } if(p*x>q*t){ return; } for(int i=x;i<=a;i++){ if(nex*i>a){ return; } int tx=p*i-q; if(tx>=0){ dfs(tx,q*i,nex*i,i,t-1); } } } int main(){ int p,q,n; while(1); while(cin>>p>>q>>a>>n && p!=0 && q!=0 && a!=0 && n!=0){ cnt=0; dfs(p,q,1,1,n); cout<<cnt<<endl; } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。