tyvj1080 N皇后
描述
检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。
列号
1 2 3 4 5 6
-------------------------
1 | | O | | | | |
-------------------------
2 | | | | O | | |
-------------------------
3 | | | | | | O |
-------------------------
4 | O | | | | | |
-------------------------
5 | | | O | | | |
-------------------------
6 | | | | | O | |
-------------------------
上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下:
行号 1 2 3 4 5 6
列号 2 4 6 1 3 5
这只是跳棋放置的一个解。请编一个程序找出所有跳棋放置的解。并把它们以上面的序列方法输出。解按字典顺序排列。请输出前3个解。最后一行是解的总个数。
特别注意: 对于更大的N(棋盘大小N x N)你的程序应当改进得更有效。不要事先计算出所有解然后只输出(或是找到一个关于它的公式),这是作弊。如果你坚持作弊,那么你登陆tyvj的帐号将被无警告删除
输入格式
一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的。
输出格式
前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。
测试样例1
输入
6
输出
2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4
先水图论,现在又开始水搜索,感觉自己已经不会搜索了。
水~
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; const int maxn=15; int n,tot,ans[maxn]; bool l[maxn],jia[maxn*2],jian[maxn*2]; void p() { for(int i=1;i<=n;++i) printf("%d ",ans[i]); printf("\n"); } void s(int pos) { if(pos==n+1) { if((++tot)<=3) p(); return ; } for(int i=1;i<=n;++i) { if(l[i]||jia[pos+i]||jian[pos-i+n]) continue; l[i]=jia[pos+i]=jian[pos-i+n]=1; ans[pos]=i;s(pos+1); l[i]=jia[pos+i]=jian[pos-i+n]=0; } } int main() { cin>>n; s(1); cout<<tot; return 0; }
codevs2080 特殊的质数肋骨
题目描述 Description
农民约翰的母牛总是产生最好的肋骨。 你能通过农民约翰和美国农业部标记在每根肋骨上的数字认出它们。 农民约翰确定他卖给买方的是真正的质数肋骨,是因为从右边开始切下肋骨,每次还剩下的肋骨上的数字都组成一个质数,举例来说: 7 3 3 1 全部肋骨上的数字 7331是质数;三根肋骨 733是质数;二根肋骨 73 是质数;当然,最后一根肋骨 7 也是质数。 7331 被叫做长度 4 的特殊质数。 写一个程序对给定的肋骨的数目 N(1<=N<=8),求出所有的特殊质数。 数字1不被看作一个质数。
输入描述 Input Description
单独的一行包含N。
输出描述 Output Description
按顺序输出长度为 N 的特殊质数,每行一个。
样例输入 Sample Input
4
样例输出 Sample Output
2333 2339 2393 2399 2939 3119 3137 3733 3739 3793 3797 5939 7193 7331 7333 7393 再来一发
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; const int maxn=10; int n,ans[maxn]; bool ok(int x) { if(x==1) return 0; int y=sqrt(x); for(int i=2;i<=y;++i) if(x%i==0) return 0; return 1; } void s(int pos,long long x) { if(!ok(x)) return; if(pos==n+1) { printf("%lld\n",x); return; } for(int i=1;i<=9;++i) { ans[pos]=i;s(pos+1,x*10+i); } } int main() { cin>>n; s(1,0); return 0; }
RQNOJ67 选数
题目描述
已知 n 个整数 x1,x2,…,xn,以及一个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:
3+7+12=22 3+7+19=29 7+12+19=38 3+12+19=34。
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=29)。
输入格式
键盘输入,格式为:
n , k (1<=n<=20,k<n)
x1,x2,…,xn (1<=xi<=5000000)
输出格式
屏幕输出,格式为:
一个整数(满足条件的种数)。
样例输入
4 3
3 7 12 19
样例输出
1
感觉还是弄一点不是这么无脑的搜索来刷好一点
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; const int maxn=20+5; int n,k,a[maxn],tot; bool ok(int x) { if(x<=1) return 0; int y=sqrt(x); for(int i=2;i<=y;++i) if(x%i==0) return 0; return 1; } void s(int pos,int f,int x) { if(f==k) { if(ok(x)) tot++; return; } if(pos>n) return; s(pos+1,f,x); s(pos+1,f+1,x+a[pos]); } int main() { cin>>n>>k; for(int i=1;i<=n;++i) cin>>a[i]; s(1,0,0); cout<<tot; return 0; }
codevs1116 四色问题
题目描述
4色问题:对平面或球面的任何一幅地图,只需要使用4种颜色就可以给地图上的每个国家填色,使得任意2个有一段公共边界的国家所填的颜色是不同的。
输入
用邻接矩阵表示地图。读入格式如下:
N(有N个国家,N不超过20)
N行用空格隔开的0/1串(1表示相邻,0表示不相邻)
输出
最多的填色方案
样例输入
8
0 0 0 1 0 0 1 0
0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0
0 1 0 0 0 0 0 0
样例输出
15552
感觉自己已经堕落了。。。
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; const int maxn=20+5; int n,cl[maxn],ans; bool tu[maxn][maxn]; int get_f(int pos) { int x=15; for(int i=1;i<pos;++i) if(tu[i][pos])x-=(x&(1<<(cl[i]-1))); return x; } void s(int pos) { if(pos>n) { ans++; return; } int x=get_f(pos); for(int i=1;i<=4;++i) if(x&(1<<(i-1))) { cl[pos]=i; s(pos+1); } } int main() { cin>>n; for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) cin>>tu[i][j]; s(1); cout<<ans; return 0; }