A - 学dfs你不会放棋盘?你TM逗我!
Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u
Description
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
Sample Input
2 1
#.
.#
4 4
…#
..#.
.#..
#…
-1 -1
Sample Output
2
1
中文题目,大家都看得懂。。没什么特别的,还是DFS咯。。
//POJ 1321
//
#include <iostream>
using namespace std;
int size;
int ans;
struct newmap {
char map [10][10]; //棋盘
int x; //上一个棋子的行数
};
void DFS(newmap temp,int chess)
{
if(chess==0)
{
ans++;
return;
}
int i,j;
for(i=temp.x+1;i<=(size-chess);i++)
{
for(j=0;j<size;j++)
{
if(temp.map[i][j]=='#')
{
newmap temp2;
temp2=temp;
temp2.x=i;
int k;
for (k = i+1 ; k < size ; k ++)
{//更新棋盘,因为,不会再向该行和该行之前的棋盘搜索,故只用更新该行下同列的棋盘
temp2.map[k][j]='.';
}
DFS(temp2,chess-1);
}
}
}
}
int main()
{
int chess;
while(scanf("%d %d ",&size,&chess))
{
if(size==-1&&chess==-1)
return 0;
newmap map;
map.x=-1;
for(int i=0;i<size;i++)
{
scanf("%s",map.map[i]);
}
DFS(map,chess);
cout<<ans<<endl;
ans=0;
size=0;
chess=0;
}
}
B - 放棋盘简单,看看这个,好像很黄很暴力的样子!
Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u
Description
Given a positive integer n, write a program to find out a nonzero multiple m of n whose decimal representation contains only the digits 0 and 1. You may assume that n is not greater than 200 and there is a corresponding m containing no more than 100 decimal digits.
Input
The input file may contain multiple test cases. Each line contains a value of n (1 <= n <= 200). A line containing a zero terminates the input.
Output
For each value of n in the input print a line containing the corresponding value of m. The decimal representation of m must not contain more than 100 digits. If there are multiple solutions for a given value of n, any one of them is acceptable.
Sample Input
2
6
19
0
Sample Output
10
100100100100100100
111111111111111111
题目说的是,给你一个数,让你找一个只由1、0组成的数,使得这个数与所给数成倍数关系。
这题DFS的关键是 从1开始每一步都在当前数字的基础上*10以及*10+1这样生成的数字每一位才要么为1要么为0,如此下去,直到生成的数符合要求为止。
#include "iostream"
#include "math.h"
using namespace std;
int flag=0; //to mark if target number has been found
void dfs(unsigned long long NowNumber,int n)
{
if(NowNumber>3222222222222222222) return;
if(flag==1) return;
else
{
if(NowNumber%n==0) //当前数是n的倍数
{
cout<<NowNumber<<endl;
flag=1;
return;
}
else
{
dfs(NowNumber*10,n);
if(flag==1) return; //once the required number is found stop
dfs(NowNumber*10+1,n);
if(flag==1) return; //the same as above
}
}
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
if(n==0) return 0;
dfs(1,n); //initial start with one
flag=0;
}
return 0;
}
C - 素数搞基环?!
Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Description
A ring is compose of n circles as shown in diagram. Put natural number 1, 2, …, n into each circle separately, and the sum of numbers in two adjacent circles should be a prime.
Note: the number of first circle should always be 1.
Input
n (0 < n < 20).
Output
The output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements. Print solutions in lexicographical order.
You are to write a program that completes above process.
Print a blank line after each case.
Sample Input
6
8
Sample Output
Case 1:
1 4 3 2 5 6
1 6 5 2 3 4
Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
输入一个n,代表这个环上有n个圈,往这个n个圈里不重复地分别填入1~n。第一个圈总是填的1。同时还要求相邻的数之和是质数。本题需要特别处理是第n个环所填的数,因为与这个位置相邻的两个环中,有一个是起点。
#include "iostream"
using namespace std;
int num_mark[9999]; //0 hasnt been used 1 used
int ncase=0;
bool is_prime(int n)
{
if(n<2)
return false;
for (int i=2;i*i<=n;i++)
{
if(n % i == 0)
return false;
}
return true;
}
void dfs(int n,int pos,int circle[]) //i is current number
{
if(pos>=n)
{
//print
int i=1;
for(i=1;i<=n;i++)
{
cout<<circle[i];
if(i!=n)
cout<<" ";
if(i==n)
cout<<endl;
}
return;
}
else
{
for(int i=1;i<=n;i++)
{
if(num_mark[i]==0)
{
if((pos+1)==n) //if next pos reach the last loop
{
if(is_prime(i+circle[1])&&is_prime(i+circle[pos]))
{
num_mark[i]=1;
circle[pos+1]=i;
dfs(n,pos+1,circle);
num_mark[i]=0;
}
}
else
{
if(is_prime(i+circle[pos]))
{
num_mark[i]=1;
circle[pos+1]=i;
dfs(n,pos+1,circle);
num_mark[i]=0;
}
}
}
}
}
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
ncase++;
memset(num_mark,0,sizeof(num_mark));
num_mark[1]=1;
int circle[25];
circle[1]=1;
cout<<"Case "<<ncase<<":"<<endl;
dfs(n,1,circle);
cout<<endl;
}
}