算法协会寒假训练Four(搜索+二分)

A - Prime Ring Problem

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
#include<iostream>
#include<cstring>
using namespace std;
int n,cnt,num=1;
int a[25];
int vis[25];
int prime[25]={0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0};
void dfs(int x){
	if(cnt==n-1&&prime[a[cnt]+1]){
		for(int i=0;i<n;i++){
			if(i) printf(" ");
			printf("%d",a[i]);
		}		
		printf("\n");
	}
	for(int i=2;i<=n;i++){
		if(!vis[i]&&prime[x+i]){ //
			vis[i]=1;
			a[++cnt]=i;   //
			dfs(i);
			vis[i]=0;
			cnt--;
		}
	}
}
int main(){
	while(~scanf("%d",&n)){
		cnt=0;
		memset(a,0,sizeof a);
		memset(vis,0,sizeof vis);
		a[0]=1;
		printf("Case %d:\n",num++);
		dfs(1);
		printf("\n");
	}
	return 0;
} 

 

B - Oil Deposits

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
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m;
char mp[105][105];
int mov[8][2]={{1,1},{-1,-1},{1,-1},{-1,1},{1,0},{-1,0},{0,1},{0,-1}};
void dfs(int x,int y){
	mp[x][y]='*';
	for(int i=0;i<8;i++){
		int xx=x+mov[i][0];
		int yy=y+mov[i][1];
		if(mp[xx][yy]!='@'||xx<0||xx>=m||yy<0||yy>=n) 
			continue;
		else dfs(xx,yy);
	}
}
int main(){
	while(~scanf("%d%d",&m,&n)&&m){   //shao &
		int sum=0;
		for(int i=0;i<m;i++)
			scanf("%s",mp[i]);
		for(int i=0;i<m;i++){
			for(int j=0;j<n;j++){
				if(mp[i][j]=='@'){
					dfs(i,j);
					sum++;
				}
					
			}
		}
		printf("%d\n",sum); // duo &
	}
	return 0;
} 

 

C - 迷宫问题 

定义一个二维数组:

int maze[5][5] = {

	0, 1, 0, 0, 0,

	0, 1, 0, 1, 0,

	0, 0, 0, 0, 0,

	0, 1, 1, 1, 0,

	0, 0, 0, 1, 0,

};


它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

Input

一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。

Output

左上角到右下角的最短路径,格式如样例所示。

Sample Input

0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

Sample Output

(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
int cnt=1;
int mp[8][8];
int vis[8][8];
int mov[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
struct node {
	int x,y,pre;
} p[30];
queue<node> q;
void Print(int n) {
	if(p[n].pre!=-1) {
		Print(p[n].pre);
		printf("(%d, %d)\n",p[n].x,p[n].y);
	}
}
bool judge(int x,int y) {
	if(x>=5||x<0||y>=5||y<0||vis[x][y]||mp[x][y]) return false;
	return true;
}
void bfs(int x,int y) {
	int front=0;
	p[front].x=x;
	p[front].y=y;
	p[front].pre=-1;
	q.push(p[front]);
	while(!q.empty()) {
		node tmp=q.front();
		q.pop();
		for(int i=0; i<4; i++) {
			int xx=tmp.x+mov[i][0];
			int yy=tmp.y+mov[i][1];
			if(judge(xx,yy)) {
				vis[xx][yy]=1;
				p[cnt].x=xx;
				p[cnt].y=yy;
				p[cnt].pre=front;
				q.push(p[cnt++]);
				if(xx==4&&yy==4) Print(front);
			}
		}
		front++;
	}
}
int main() {
	for(int i=0; i<5; i++)
		for(int j=0; j<5; j++)
			scanf("%d",&mp[i][j]);
	printf("(0, 0)\n");
	bfs(0,0);
	printf("(4, 4)\n");
	return 0;
}
zg:
#include<iostream>
#include<queue>
using namespace std;
int vis[6][6],mp[6][6];
struct node {
	int x,y;
} pre[10][10];
int dir[4][2]= {{0,1},{0,-1},{1,0},{-1,0}};
void bfs(node a) {
	queue<node> q;
	node b,c;
	q.push(a);
	vis[a.x][a.y]=1;
	while(!q.empty()) {
		b=q.front();
		q.pop();
		if(b.x==4&&b.y==4) {
			return;
		}
		for(int i=0; i<4; i++) {
			c.x=b.x+dir[i][0];
			c.y=b.y+dir[i][1];
			if(!vis[c.x][c.y]&&(c.x>=0&&c.x<5)&&(c.y>=0&&c.y<5)) {
				q.push(c);
				pre[c.x][c.y].x=b.x;
				pre[c.x][c.y].y=b.y;//此步记录c的上一个点是b
				vis[c.x][c.y]=1;
			}
		}
	}
}
void print(int x,int y) {//递归倒着打印
	if(x==0&&y==0) {
		printf("(0, 0)\n");
		return;
	} else
		print(pre[x][y].x,pre[x][y].y);
	printf("(%d, %d)\n",x,y);
}
int main() {
	for(int i=0; i<5; i++)
		for(int j=0; j<5; j++) {
			scanf("%d",&mp[i][j]);
			{
				if(mp[i][j]==1)
					vis[i][j]=1;
			}
		}
	node a;
	a.x=0,a.y=0;
	bfs(a);
	print(4,4);
	return 0;
}

 

 

D - N皇后问题 

在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
 

Input

共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。

Output

共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。

Sample Input

1
8
5
0

Sample Output

1
92
10
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int n,sum;
int f[15];
int a[15];
void dfs(int x) {
	if(x>n) {
		sum++;
		return;
	}
	int r,c;
	for(c=1; c<=n; c++) {
		for(r=1;r<x;r++)
			if(c==a[r]) break; 
		if(r<x) continue;
		for(r=1;r<x;r++)
			if(x-r==abs(a[r]-c)) break;
		if(r<x) continue;
		a[x]=c;
		dfs(x+1);	
	}
}
int main() {
	for(n=1; n<=10; n++) {
		sum=0;
		dfs(1);
		f[n]=sum;
	}
	while(cin>>n&&n)
		cout<<f[n]<<endl;
	return 0;
}
zg赞赞的条理清晰版
#include<iostream>
#include<cmath>
using namespace std;
int n,cnt,y[15],re[15];//y数组用来存放皇后的列标
bool check(int x) {//已经放置好了x-1个皇后
	for(int i=1; i<x; i++) {
		if(abs(x-i)==abs(y[x]-y[i])||y[x]==y[i])
			return 0;
	}
	return 1;
	/*按照行优先做的,所以一行肯定不会有冲突的,只需要判断对角
	的情况和列是否有冲突的; abs(x-i)==abs(y[x]-y[i])和y[x]==y[i]
	分别判断对角和列*/
}
int dfs(int t) {
	if(t>n) cnt++;
	else
		for(int i=1; i<=n; i++) {
			y[t]=i;//这个t既可以说是安置的第t个,亦可以是第t个的行坐标
			if(check(t)) { //因为肯定每行都有一个,安置第t个肯定在第t行
				dfs(t+1);
			}
		}
	return cnt;
}
int main(){
	for(n=1;n<=10;n++){
		cnt=0;
		re[n]=dfs(1);//一开始没有存在数组里,直接在下面cout<<dfs(1),结果T了
	}
	while(cin>>n&&n){
	    cout<<re[n]<<endl;
	}
	return 0;
}

 

 E - Maze

Pavel loves grid mazes. A grid maze is an n × m rectangle maze where each cell is either empty, or is a wall. You can go from one cell to another only if both cells are empty and have a common side.

Pavel drew a grid maze with all empty cells forming a connected area. That is, you can go from any empty cell to any other one. Pavel doesn't like it when his maze has too little walls. He wants to turn exactly k empty cells into walls so that all the remaining cells still formed a connected area. Help him.

Input

The first line contains three integers n, m, k (1 ≤ n, m ≤ 500, 0 ≤ k < s), where n and m are the maze's height and width, correspondingly, k is the number of walls Pavel wants to add and letter s represents the number of empty cells in the original maze.

Each of the next n lines contains m characters. They describe the original maze. If a character on a line equals ".", then the corresponding cell is empty and if the character equals "#", then the cell is a wall.

Output

Print n lines containing m characters each: the new maze that fits Pavel's requirements. Mark the empty cells that you transformed into walls as "X", the other cells must be left without changes (that is, "." and "#").

It is guaranteed that a solution exists. If there are multiple solutions you can output any of them.

Examples

Input

3 4 2
#..#
..#.
#...

Output

#.X#
X.#.
#...

Input

5 4 5
#...
#.#.
.#..
...#
.#.#

Output

#XXX
#X#.
X#..
...#
.#.#
#include<iostream>
#include<cstring>
using namespace std;
int n,m,k;
char mp[505][505];
bool vis[505][505];
void dfs(int x,int y){
	if(x>=n||x<0||y>=m||y<0) return;
	if(mp[x][y]!='.'||vis[x][y]) return;
	vis[x][y]=true;
	dfs(x+1,y);dfs(x-1,y);
	dfs(x,y+1);dfs(x,y-1);
	if(k){
		mp[x][y]='X';
		k--;
	}
}
int main(){
	memset(vis,false,sizeof vis);
	cin>>n>>m>>k;
	for(int i=0;i<n;i++)
		scanf("%s",&mp[i]);
	for(int i=0;i<n&&k;i++)
		for(int j=0;j<m&&k;j++){
			if(mp[i][j]=='.'&&!vis[i][j])
				dfs(i,j);
		}
	for(int i=0;i<n;i++)
		printf("%s\n",mp[i]);
	return 0;
} 

 

 

F - Funky Numbers

As you very well know, this year's funkiest numbers are so called triangular numbers (that is, integers that are representable as , where k is some positive integer), and the coolest numbers are those that are representable as a sum of two triangular numbers.

A well-known hipster Andrew adores everything funky and cool but unfortunately, he isn't good at maths. Given number n, help him define whether this number can be represented by a sum of two triangular numbers (not necessarily different)!

Input

The first input line contains an integer n (1 ≤ n ≤ 109).

Output

Print "YES" (without the quotes), if n can be represented as a sum of two triangular numbers, otherwise print "NO" (without the quotes).

Examples

Input

256

Output

YES

Input

512

Output

NO

Note

In the first sample number .

In the second sample number 512 can not be represented as a sum of two triangular numbers.

#include<iostream>
#include<cmath>
using namespace std;
int main(){
	int n,s1,s2,OK=0;
	int l,r,mid;
	cin>>n;
	for(int i=1;i<sqrt(2*n);i++){
		s1=i*(i+1)>>1;
		l=i,r=sqrt(n*2);
		while(l<=r){
			mid=(l+r)>>1;
			s2=mid*(mid+1)>>1;
			if(s1+s2==n){
				OK=1;
				break;
			}
			else if(s1+s2>n)
				r=mid-1;
			else l=mid+1;
		}
	}
	if(OK) cout<<"YES\n";
	else cout<<"NO\n";
	return 0;
}

 

G - Frodo and pillows 

n hobbits are planning to spend the night at Frodo's house. Frodo has n beds standing in a row and m pillows (n ≤ m). Each hobbit needs a bed and at least one pillow to sleep, however, everyone wants as many pillows as possible. Of course, it's not always possible to share pillows equally, but any hobbit gets hurt if he has at least two pillows less than some of his neighbors have.

Frodo will sleep on the k-th bed in the row. What is the maximum number of pillows he can have so that every hobbit has at least one pillow, every pillow is given to some hobbit and no one is hurt?

Input

The only line contain three integers n, m and k (1 ≤ n ≤ m ≤ 109, 1 ≤ k ≤ n) — the number of hobbits, the number of pillows and the number of Frodo's bed.

Output

Print single integer — the maximum number of pillows Frodo can have so that no one is hurt.

Examples

Input

4 6 2

Output

2

Input

3 10 3

Output

4

Input

3 6 1

Output

3

Note

In the first example Frodo can have at most two pillows. In this case, he can give two pillows to the hobbit on the first bed, and one pillow to each of the hobbits on the third and the fourth beds.

In the second example Frodo can take at most four pillows, giving three pillows to each of the others.

In the third example Frodo can take three pillows, giving two pillows to the hobbit in the middle and one pillow to the hobbit on the third bed.

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm> 
#define ll long long
using namespace std;
ll n,m,k,sum;
bool judge(ll mid){
	sum=mid;
	if(mid-1>k-1) 
		sum+=(mid+mid-k)*(k-1)/2;
	else{
		sum+=(0+mid-1)*mid/2;
		sum+=((k-1)-(mid-1));
	}
	if(mid-1>=n-k)
		sum+=(mid-1+(mid-(n-k)))*(n-k)/2;
	else{
		sum+=(0+mid-1)*mid/2;
		sum+=(n-k-(mid-1));
	}
	if(sum<=m) return true;
	else return false;
}
int main(){
	cin>>n>>m>>k;
	ll l=1,r=m,mid;
	while(l<=r){
		mid=(l+r)/2;
		if(judge(mid)) l=mid+1;
		else r=mid-1;
	}
	mid=(l+r)/2;
	cout<<mid;
	return 0;
}

 

 H - 4 Values whose Sum is 0

The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute how many quadruplet (a, b, c, d ) ∈ A x B x C x D are such that a + b + c + d = 0 . In the following, we assume that all lists have the same size n .

Input

The first line of the input file contains the size of the lists n (this value can be as large as 4000). We then have n lines containing four integer values (with absolute value as large as 2 28 ) that belong respectively to A, B, C and D .

Output

For each input file, your program has to write the number quadruplets whose sum is zero.

Sample Input

6
-45 22 42 -16
-41 -27 56 30
-36 53 -37 77
-36 30 -75 -46
26 -38 -10 62
-32 -54 -6 45

Sample Output

5

Hint

Sample Explanation: Indeed, the sum of the five following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm> 
using namespace std;
const int MAX=4005;
int a[MAX],b[MAX],c[MAX],d[MAX];
int cd[MAX*MAX];
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
		scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			cd[i*n+j]=c[i]+d[j];
	sort(cd,cd+n*n);
	int tmp,sum=0;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			tmp=-(a[i]+b[j]);
			sum+=upper_bound(cd,cd+n*n,tmp)-lower_bound(cd,cd+n*n,tmp); 
		}
	}
	cout<<sum;
	return 0;
}

 

 I - Aggressive cows

Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,...,xN (0 <= xi <= 1,000,000,000).

His C (2 <= C <= N) cows don't like this barn layout and become aggressive towards each other once put into a stall. To prevent the cows from hurting each other, FJ want to assign the cows to the stalls, such that the minimum distance between any two of them is as large as possible. What is the largest minimum distance?

Input

* Line 1: Two space-separated integers: N and C

* Lines 2..N+1: Line i+1 contains an integer stall location, xi

Output

* Line 1: One integer: the largest minimum distance

Sample Input

5 3
1
2
8
4
9

Sample Output

3

Hint

OUTPUT DETAILS:

FJ can put his 3 cows in the stalls at positions 1, 4 and 8, resulting in a minimum distance of 3.

Huge input data,scanf is recommended.

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm> 
using namespace std;
int n,c;
int a[100002];
bool judge(int mid){
	int t=a[0],cnt=1;
	for(int i=1;i<n;i++){
		if(a[i]-t>=mid){
			cnt++;
			t=a[i]; //比较基准更改 
			if(cnt>=c) return true;
		}
	}
	return false;
}
int main(){
	cin>>n>>c;
	for(int i=0;i<n;i++)
		scanf("%d",&a[i]);
	sort(a,a+n);
	int l=0,r=a[n-1],mid;
	while(l<=r){
		mid=(l+r)>>1;
		if(judge(mid)) l=mid+1;
		else r=mid-1;
	}
	cout<<r;
	return 0;
}

 

J - Pie 

My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I have a number N of them, of various tastes and of various sizes. F of my friends are coming to my party and each of them gets a piece of pie. This should be one piece of one pie, not several small pieces since that looks messy. This piece can be one whole pie though.

My friends are very annoying and if one of them gets a bigger piece than the others, they start complaining. Therefore all of them should get equally sized (but not necessarily equally shaped) pieces, even if this leads to some pie getting spoiled (which is better than spoiling the party). Of course, I want a piece of pie for myself too, and that piece should also be of the same size.

What is the largest possible piece size all of us can get? All the pies are cylindrical in shape and they all have the same height 1, but the radii of the pies can be different.

Input

One line with a positive integer: the number of test cases. Then for each test case:
---One line with two integers N and F with 1 <= N, F <= 10 000: the number of pies and the number of friends.
---One line with N integers ri with 1 <= ri <= 10 000: the radii of the pies.

Output

For each test case, output one line with the largest possible volume V such that me and my friends can all get a pie piece of size V. The answer should be given as a floating point number with an absolute error of at most 10^(-3).

Sample Input

3
3 3
4 3 3
1 24
5
10 5
1 4 2 3 4 5 6 5 4 2

Sample Output

25.1327
3.1416
50.2655
#include<iostream>
#include<cmath>
#define PI 3.1415926535898
using namespace std;
double a[10005];
int main(){
	int t,n,f,sum;
	double r,L,R=0,Mid;
	cin>>t;
	while(t--){
		scanf("%d%d",&n,&f);
		for(int i=0;i<n;i++){
			scanf("%lf",&r);
			a[i]=PI*r*r;
			R=max(R,a[i]);
		}
		L=0;
		while(R-L>1e-5){
			Mid=(L+R)/2;
			sum=0;
			for(int i=0;i<n;i++)
				sum+=(int)(a[i]/Mid);
			if(sum>=(f+1)) L=Mid;
			else R=Mid;
		}
		printf("%.4f\n",L);
	}
	return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值