Oil Deposits
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions:20263 | Accepted: 10621 |
Description
The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid.
Input
The input contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket.
Output
are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets.
Sample Input
1 1 * 3 5 *@*@* **@** *@*@* 1 8 @@****@* 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ 0 0
Sample Output
0 1 2 2
Source
题意:求连通的@总共有几块(上下左右左上右下右上左下都算一块),典型dfs题。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <conio.h>
using namespace std;
char map[105][105];
int dx[3]={-1,0,1};
int dy[3]={-1,0,1};
int m,n;
char ch;
int judge(int x,int y)
{
if (0<=x&&x<m&&0<=y&&y<n) return 1;
else return 0;
}
void dfs(int i,int j)
{
if (map[i][j]=='@')
{
map[i][j]='*';
for (int i1=0;i1<3;i1++)
for (int j1=0;j1<3;j1++)
if(dx[i1]||dy[j1]&&judge(i+dx[i1],j+dy[j1])) dfs(i+dx[i1],j+dy[j1]);
}
}
int main()
{
while (scanf("%d%d",&m,&n)!=EOF)
{
scanf("%c",&ch);
if (ch==' ') getchar();
if (n==0 && m==0) break;
int cnt=0;
for (int i=0;i<m;i++)
{
for (int j=0;j<n;j++)
scanf("%c",&map[i][j]);
getchar();
}
for (int i=0;i<m;i++)
for (int j=0;j<n;j++)
if (map[i][j]=='@') {cnt++; dfs(i,j);}
cout << cnt << endl;
}
return 0;
}
Sum It Up
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions:8564 | Accepted: 4381 |
Description
Given a specified total t and a list of n integers, find all distinct sums using numbers from the list that add up to t. For example, if t = 4, n = 6, and the list is [4, 3, 2, 2, 1, 1], then there are four different sums that equal 4: 4, 3+1, 2+2, and 2+1+1. (A number can be used within a sum as many times as it appears in the list, and a single number counts as a sum.) Your job is to solve this problem in general.
Input
The input will contain one or more test cases, one per line. Each test case contains t, the total, followed by n, the number of integers in the list, followed by n integers x 1 , . . . , x n . If n = 0 it signals the end of the input; otherwise, t will be a positive integer less than 1000, n will be an integer between 1 and 12 (inclusive), and x 1 , . . . , x n will be positive integers less than 100. All numbers will be separated by exactly one space. The numbers in each list appear in nonincreasing order, and there may be repetitions.
Output
For each test case, first output a line containing `Sums of', the total, and a colon. Then output each sum, one per line; if there are no sums, output the line `NONE'. The numbers within each sum must appear in nonincreasing order. A number may be repeated in the sum as many times as it was repeated in the original list. The sums themselves must be sorted in decreasing order based on the numbers appearing in the sum. In other words, the sums must be sorted by their first number; sums with the same first number must be sorted by their second number; sums with the same first two numbers must be sorted by their third number; and so on. Within each test case, all sums must be distinct; the same sum cannot appear twice.
Sample Input
4 6 4 3 2 2 1 1 5 3 2 1 1 400 12 50 50 50 50 50 50 25 25 25 25 25 25 0 0
Sample Output
Sums of 4: 4 3+1 2+2 2+1+1 Sums of 5: NONE Sums of 400: 50+50+50+50+50+50+25+25+25+25 50+50+50+50+50+25+25+25+25+25+25
Source
题意:给你一个t然后从n个数中找到一个子串和为t。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int a[1005],b[1005];
int n,t,cnt;
int cmp(int a,int b)
{
return a>b;
}
void dfs(int s,int p,int l)
{
if (s>t)
return;
else if(s==t)
{
printf("%d",b[0]);
for(int i=1;i<l;i++)
printf("+%d",b[i]);
printf("\n");
cnt++;
}
else
{
for(int i=p;i<n;i++)
{
b[l]=a[i];
dfs(s+a[i],i+1,l+1);
while (i+1<n&&a[i]==a[i+1])
i++;
}
}
}
int main()
{
while(cin >> t >> n && n && t)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for (int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n,cmp);
printf("Sums of %d:\n",t);
cnt=0;
dfs(0,0,0);
if (!cnt) printf("NONE\n");
}
}
N皇后问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 29001 Accepted Submission(s): 12749
Problem Description
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input
1 8 5 0
Sample Output
1 92 10
Author
cgf
Source
题意:n皇后问题,直接用的以前写的代码。
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int sum=0,n;
int a[15][15],b[15];
int ju(int i,int j)
{
if (1<=i&&i<=n&&1<=j&&j<=n) return 1;
else return 0;
}
int judge(int i,int j)
{
int k,flag=1;
for (k=1;k<=n;k++)
{
if (ju(i-k,j)&&a[i-k][j]==1) {flag=0;break;}
else if (ju(i-k,j-k)&&a[i-k][j-k]==1) {flag=0;break;}
else if (ju(i-k,j+k)&&a[i-k][j+k]==1) {flag=0;break;}
}
return flag;
}
void dfs(int i,int j)
{
while (j<=n)
{
if (judge(i,j))
{
a[i][j]=1;
if (i==n) sum++;
else dfs(i+1,1);
a[i][j]=0;
}
j++;
}
}
int main()
{
for (int i=1;i<=10;i++)
{
n=i; sum=0;
memset(a,0,sizeof(a));
dfs(1,1);
b[i]=sum;
//printf("%d\n",b[i]);
}
while(cin >> n && n)
{
printf("%d\n",b[n]);
}
return 0;
}
Sudoku
Time Limit: 2000MS | Memory Limit: 65536K | |||
Total Submissions:22005 | Accepted:10431 | Special Judge |
Description
Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure. In some of the cells are written decimal digits from 1 to 9. The other cells are empty. The goal is to fill the empty cells with decimal digits from 1 to 9, one digit per cell, in such way that in each row, in each column and in each marked 3x3 subsquare, all the digits from 1 to 9 to appear. Write a program to solve a given Sudoku-task.
Input
The input data will start with the number of the test cases. For each test case, 9 lines follow, corresponding to the rows of the table. On each line a string of exactly 9 decimal digits is given, corresponding to the cells in this line. If a cell is empty it is represented by 0.
Output
For each test case your program should print the solution in the same format as the input data. The empty cells have to be filled according to the rules. If solutions is not unique, then the program may print any one of them.
Sample Input
1 103000509 002109400 000704000 300502006 060000050 700803004 000401000 009205800 804000107
Sample Output
143628579 572139468 986754231 391542786 468917352 725863914 237481695 619275843 854396127
Source
题意:填完数独,这题很容易超时,状态需要存的合理。
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int map[10][10],r[10][10],c[10][10],t[3][3][10];
int flag;
char ch;
void judge(int n)
{
int x=n/9,y=n%9;
if (flag) return;
if (n==81)
{
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
printf("%d",map[i][j]);
}
printf("\n");
}
flag=1;
return;
}
if (map[x][y]==0)
{
for(int i=1;i<=9;i++)
{
if (!(r[x][i]||c[y][i]||t[x/3][y/3][i]))
{
map[x][y]=i;
t[x/3][y/3][i]=r[x][i]=c[y][i]=1;
judge(n+1);
t[x/3][y/3][i]=r[x][i]=c[y][i]=0;
map[x][y]=0;
}
}
}
else judge(n+1);
}
int main()
{
int n; cin >> n; getchar();
while(n--)
{
flag=0;
memset(map,0,sizeof(map));
memset(c,0,sizeof(c));
memset(r,0,sizeof(r));
memset(t,0,sizeof(t));
for (int i=0;i<9;i++)
{
for (int j=0;j<9;j++)
{
scanf("%c",&ch);
map[i][j]=ch-'0';
if (map[i][j])
{
c[j][map[i][j]]=1;
r[i][map[i][j]]=1;
t[i/3][j/3][map[i][j]]=1;
}
}
getchar();
}
judge(0);
}
return 0;
}
A Knight's Journey
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions:48884 | Accepted: 16589 |
Description
Background
The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey
around the world. Whenever a knight moves, it is two squares in one direction and one square perpendicular to this. The world of a knight is the chessboard he is living on. Our knight lives on a chessboard that has a smaller area than a regular 8 * 8 board, but it is still rectangular. Can you help this adventurous knight to make travel plans?
Problem
Find a path such that the knight visits every square once. The knight can start and end on any square of the board.
The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey
around the world. Whenever a knight moves, it is two squares in one direction and one square perpendicular to this. The world of a knight is the chessboard he is living on. Our knight lives on a chessboard that has a smaller area than a regular 8 * 8 board, but it is still rectangular. Can you help this adventurous knight to make travel plans?
Problem
Find a path such that the knight visits every square once. The knight can start and end on any square of the board.
Input
The input begins with a positive integer n in the first line. The following lines contain n test cases. Each test case consists of a single line with two positive integers p and q, such that 1 <= p * q <= 26. This represents a p * q chessboard, where p describes how many different square numbers 1, . . . , p exist, q describes how many different square letters exist. These are the first q letters of the Latin alphabet: A, . . .
Output
The output for every scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1. Then print a single line containing the lexicographically first path that visits all squares of the chessboard with knight moves followed by an empty line. The path should be given on a single line by concatenating the names of the visited squares. Each square name consists of a capital letter followed by a number.
If no such path exist, you should output impossible on a single line.
If no such path exist, you should output impossible on a single line.
Sample Input
3 1 1 2 3 4 3
Sample Output
Scenario #1: A1 Scenario #2: impossible Scenario #3: A1B3C1A2B4C2A3B1C3A4B2C4
Source
题意:跳马问题,从A按一定顺序跳到B,可能的话输出路径,否则输出impossible。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int map[30][30],path[30][30],cnt=0,flag,p,q;
int dx[8]={-1,1,-2,2,-2,2,-1,1};
int dy[8]={-2,-2,-1,-1,1,1,2,2};
int judge(int x,int y)
{
if(x>=1&&x<=p&&y>=1&&y<=q&&!map[x][y]&&!flag) return 1;
else return 0;
}
void dfs(int r,int c,int step)
{
path[step][0]=r;
path[step][1]=c;
if (step==p*q)
{
flag=1;
return;
}
for(int i=0;i<8;i++)
{
int nx=r+dx[i];
int ny=c+dy[i];
if(judge(nx,ny))
{
map[nx][ny]=1;
dfs(nx,ny,step+1);
map[nx][ny]=0;
}
}
}
int main()
{
int n; cin >> n;
while(n--)
{
flag=0;
memset(map,0,sizeof(map));
memset(path,0,sizeof(path));
scanf("%d%d",&p,&q);
map[1][1]=1;
dfs(1,1,1);
printf("Scenario #%d:\n",++cnt);
if(flag)
{
for(int i=1;i<=p*q;i++)
printf("%c%d",path[i][1]-1+'A',path[i][0]);
}
else
printf("impossible");
printf("\n");
if(n!=0)
printf("\n");
}
return 0;
}
Prime Ring Problem
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 59738 Accepted Submission(s): 25849
Problem 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.
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.
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
Source
题意:n个数组成一个环使得相邻两个数之和为素数。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int p[50],a[25],vis[25],n,cnt=0;
void dfs(int pos)
{
if (pos == n && p[a[0]+a[n-1]])
{
printf("%d",a[0]);
for (int i=1;i<n;i++)
printf(" %d",a[i]);
printf("\n");
}
else for (int i=2;i<=n;i++)
{
if (!vis[i]&&p[i+a[pos-1]])
{
a[pos]=i;
vis[i]=1;
dfs(pos+1);
vis[i]=0;
}
}
}
int main()
{
memset(p,1,sizeof(p)); p[1]=0;
for (int i=2;i<=40;i++)
{
if (p[i])
{
for (int j=2*i;j<=40;j+=i)
p[j]=0;
}
}
while(cin >> n)
{
a[0]=1;
memset(vis,0,sizeof(vis));
printf("Case %d:\n",++cnt);
dfs(1);
printf("\n");
}
return 0;
}