Codeforces Round #639 (Div. 2) 【A—D思路及题解】

A. Puzzle Pieces

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output

You are given a special jigsaw puzzle consisting of n⋅m identical pieces. Every piece has three tabs and one blank, as pictured below.
在这里插入图片描述
The jigsaw puzzle is considered solved if the following conditions hold:

The pieces are arranged into a grid with n rows and m columns.
For any two pieces that share an edge in the grid, a tab of one piece fits perfectly into a blank of the other piece.
Through rotation and translation of the pieces, determine if it is possible to solve the jigsaw puzzle.

Input
The test consists of multiple test cases. The first line contains a single integer t (1≤t≤1000) — the number of test cases. Next t lines contain descriptions of test cases.

Each test case contains two integers n and m (1≤n,m≤10^5).

Output
For each test case output a single line containing “YES” if it is possible to solve the jigsaw puzzle, or “NO” otherwise. You can print each letter in any case (upper or lower).

Example
input
3
1 3
100000 100000
2 2

output
YES
NO
YES

Note
For the first test case, this is an example solution:
在这里插入图片描述
For the second test case, we can show that no solution exists.

For the third test case, this is an example solution:
在这里插入图片描述
题解:

用凹凸部分进行总数计算:每个图形三个凸点,一个凹点,组成后的图形共 3* m* n 个凸点,外围最多有
2*(m+n)个凸点,据此判断能否组成图形即可。

#include <bits/stdc++.h>
using namespace std;
long long t,n,m;

int main()
{
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--) {
        cin>>n>>m;
        if(m*n <= m+n)    cout<<"YES"<<endl;
        else    cout<<"NO"<<endl;
    }
    return 0;
}

还有另一种更为简单粗暴的方法…需要敏锐的洞察力和直觉 ??? ORZ6(就是slow了一倍 !)

#include <bits/stdc++.h>
using namespace std;

int main()
{
	ios::sync_with_stdio(false); //这里加了也没用,hhh 
	int u; 
	cin>>u;
	while(u--)	{
		int n,m; 
		cin>>n>>m;
		if(n==1 || m==1)    cout<<"YES"<<endl; //构成一行或一列

//题目中2*2的,此时整个图形已无凹点,没法再加,所以要么单行单列,要么2*2,下有草图提示
		else if (n==2 && m==2)	  cout<<"YES"<<endl; 
		else   cout<<"NO"<<endl;
	}
}

在这里插入图片描述

B. Card Constructions

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output

A card pyramid of height 1 is constructed by resting two cards against each other. For h>1, a card pyramid of height h is constructed by placing a card pyramid of height h−1 onto a base. A base consists of h pyramids of height 1, and h−1 cards on top. For example, card pyramids of heights 1, 2, and 3 look as follows:
在这里插入图片描述
You start with n cards and build the tallest pyramid that you can. If there are some cards remaining, you build the tallest pyramid possible with the remaining cards. You repeat this process until it is impossible to build another pyramid. In the end, how many pyramids will you have constructed?

Input
Each test consists of multiple test cases. The first line contains a single integer t (1≤t≤1000) — the number of test cases. Next t lines contain descriptions of test cases.

Each test case contains a single integer n (1≤n≤109) — the number of cards.

It is guaranteed that the sum of n over all test cases does not exceed 109.

Output
For each test case output a single integer — the number of pyramids you will have constructed in the end.

Example
input
5
3
14
15
24
1

output
1
2
1
3
0

Note
In the first test, you construct a pyramid of height 1 with 2 cards. There is 1 card remaining, which is not enough to build a pyramid.

In the second test, you build two pyramids, each of height 2, with no cards remaining.

In the third test, you build one pyramid of height 3, with no cards remaining.

In the fourth test, you build one pyramid of height 3 with 9 cards remaining. Then you build a pyramid of height 2 with 2 cards remaining. Then you build a final pyramid of height 1 with no cards remaining.

In the fifth test, one card is not enough to build any pyramids.

题解1:

题意是用火柴去摆金字塔,找规律,n个火柴,每次摆必须得摆到最高的一个停下来去摆下一个,问能摆几个金字塔。
费了一番力气,得出:火柴数=(3hh+h)/2。

#include <bits/stdc++.h>
using namespace std;
int a[10000001];

int main()
{
	int t; 
	cin>>t;
	while(t--)
	{
		int n; 
		cin>>n;
		int s=0;
		while(n>=2)
		{
			while(n>=2)
			{
				for(int i=2; i<=1000000000; i++)
				{
					int h1 = ( 3*(i-1)*(i-1) +i-1) /2;
					int h2 = ( 3*i*i +i ) /2;
					if (h1 <= n && h2 > n)	{
						n -= h1;
						s++;
						break;
					}
				}
			}
		}
		cout<<s<<endl;
	}
	return 0;
}

题解2:

首先用数学方法判断它能组成的最高高度,再用总数减去最高高度所用数量,直到连高度为1的塔都组不成为止,计算即可。

#include <bits/stdc++.h>
using namespace std;
long long t,n,m,ans,cnt;

int main()
{
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--) {
        cin>>n;
        cnt=0;
        ans=(sqrt(1+24*n)-1)/6;
        while(ans>=1) {
            cnt++;
            n-=(ans+3*ans*ans)/2;
            ans=(sqrt(1+24*n)-1)/6;
        }
        cout<<cnt<<endl;
    }
    return 0;
}

C. Hilbert’s Hotel

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output

Hilbert’s Hotel is a very unusual hotel since the number of rooms is infinite! In fact, there is exactly one room for every integer, including zero and negative integers. Even stranger, the hotel is currently at full capacity, meaning there is exactly one guest in every room. The hotel’s manager, David Hilbert himself, decides he wants to shuffle the guests around because he thinks this will create a vacancy (a room without a guest).

For any integer k and positive integer n, let kmodn denote the remainder when k is divided by n. More formally, r=kmodn is the smallest non-negative integer such that k−r is divisible by n. It always holds that 0≤kmodn≤n−1. For example, 100mod12=4 and (−1337)mod3=1.

Then the shuffling works as follows. There is an array of n integers a0,a1,…,an−1. Then for each integer k, the guest in room k is moved to room number k+akmodn.

After this shuffling process, determine if there is still exactly one guest assigned to each room. That is, there are no vacancies or rooms with multiple guests.

Input
Each test consists of multiple test cases. The first line contains a single integer t (1≤t≤104) — the number of test cases. Next 2t lines contain descriptions of test cases.

The first line of each test case contains a single integer n (1≤n≤2⋅105) — the length of the array.

The second line of each test case contains n integers a0,a1,…,an−1 (−109≤ai≤109).

It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.

Output
For each test case, output a single line containing “YES” if there is exactly one guest assigned to each room after the shuffling process, or “NO” otherwise. You can print each letter in any case (upper or lower).

Example
input
6
1
14
2
1 -1
4
5 5 5 1
3
3 2 1
2
0 1
5
-239 -2 -100 -3 -11

output
YES
YES
YES
NO
NO
YES

Note
In the first test case, every guest is shifted by 14 rooms, so the assignment is still unique.

In the second test case, even guests move to the right by 1 room, and odd guests move to the left by 1 room. We can show that the assignment is still unique.

In the third test case, every fourth guest moves to the right by 1 room, and the other guests move to the right by 5 rooms. We can show that the assignment is still unique.

In the fourth test case, guests 0 and 1 are both assigned to room 3.

In the fifth test case, guests 1 and 2 are both assigned to room 2.

#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define pb push_back
     
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int t;
	cin>>t;
	
    while(t--)
	{
        int n;
		cin>>n;
        vector<int> a(n,0);
        bool ans=true;
        vector<int> v(n);
        
        for(int i=0;i<n;i++) {
            cin>>v[i];
            v[i]+=i;
            v[i]+=(1e9);
            v[i]%=n;
            a[v[i]]++;
        }
        
        for(int i=0;i<n;i++)  {
            if(a[i]==0)	 {
			    cout<<"NO"<<endl; 
			    ans=false; 
		 	    break;
			 }
        }
        if(ans) cout<<"YES"<<endl;
    }
    return 0;
}

D. Monopole Magnets

time limit per test:2 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output

A monopole magnet is a magnet that only has one pole, either north or south. They don’t actually exist since real magnets have two poles, but this is a programming contest problem, so we don’t care.

There is an n×m grid. Initially, you may place some north magnets and some south magnets into the cells. You are allowed to place as many magnets as you like, even multiple in the same cell.

An operation is performed as follows. Choose a north magnet and a south magnet to activate. If they are in the same row or the same column and they occupy different cells, then the north magnet moves one unit closer to the south magnet. Otherwise, if they occupy the same cell or do not share a row or column, then nothing changes. Note that the south magnets are immovable.

Each cell of the grid is colored black or white. Let’s consider ways to place magnets in the cells so that the following conditions are met.

1.There is at least one south magnet in every row and every column.
2.If a cell is colored black, then it is possible for a north magnet to occupy this cell after some sequence of operations from the initial placement.
3.If a cell is colored white, then it is impossible for a north magnet to occupy this cell after some sequence of operations from the initial placement.

Determine if it is possible to place magnets such that these conditions are met. If it is possible, find the minimum number of north magnets required (there are no requirements on the number of south magnets).

Input
The first line contains two integers n and m (1≤n,m≤1000) — the number of rows and the number of columns, respectively.

The next n lines describe the coloring. The i-th of these lines contains a string of length m, where the j-th character denotes the color of the cell in row i and column j. The characters “#” and “.” represent black and white, respectively. It is guaranteed, that the string will not contain any other characters.

Output
Output a single integer, the minimum possible number of north magnets required.

If there is no placement of magnets that satisfies all conditions, print a single integer −1.

Examples
input
3 3
.#.

##.
output
1

input
4 2

.#
.#

output
-1

input
4 5
…#
####.
.###.
.#…
output
2

input
2 1
.

output
-1

input
3 5



output
0

Note
In the first test, here is an example placement of magnets:
在这里插入图片描述
In the second test, we can show that no required placement of magnets exists. Here are three example placements that fail to meet the requirements. The first example violates rule 3 since we can move the north magnet down onto a white square. The second example violates rule 2 since we cannot move the north magnet to the bottom-left black square by any sequence of operations. The third example violates rule 1 since there is no south magnet in the first column.
在这里插入图片描述
In the third test, here is an example placement of magnets. We can show that there is no required placement of magnets with fewer north magnets.
在这里插入图片描述
In the fourth test, we can show that no required placement of magnets exists. Here are two example placements that fail to meet the requirements. The first example violates rule 1 since there is no south magnet in the first row. The second example violates rules 1 and 3 since there is no south magnet in the second row and we can move the north magnet up one unit onto a white square.
在这里插入图片描述
In the fifth test, we can put the south magnet in each cell and no north magnets. Because there are no black cells, it will be a correct placement.

题意:
在网格里放入两种磁铁,如果S和N在同一行或同一列且不在同一个位置那么N可以向S移动一格。现在S的个数不限,求满足以下三种条件时,N的最小个数,否则输出-1;

1.每一行每一列至少一个S。

2.如果格子是黑的,至少有一个N可以通过一系列操作从初始位置到达该格子。

3.如果格子是白的,不允许有N可以到达该格子。

思路:从样例中可以看出,首先可以先将所有黑格子放上S,然后每个黑色区域放上一个N就可,但要先判断是否满足三个条件。

条件1:如果这一行这一列有黑色格子,那么就一定至少有一个S;如果这一行无黑色格子,但这一行对应的每一列都有黑色格子,那么这一行就不能放S,因为会把到其他黑色格子的N吸过来,不符合条件3,所以对应一行白格子必须要有一列白格子对应,在其交叉处放S。
在这里插入图片描述条件2:在所有黑块放上S即可。
条件3: 从样例2可以看出,白色两边不能同时有黑色。

// D
#include <bits/stdc++.h>
using namespace std;
const int N = 1010; 
 
int n,m;
int c[N],r[N],st[N][N];
char grid[N][N];
int mov[4][2] = {0,1,0,-1,1,0,-1,0};
int vis[N][N];
 
void dfs(int i, int j)
{
	grid[i][j] = '.';
	for(int k=0; k<4; k++)
	{
		int x = i + mov[k][0];
		int y = j + mov[k][1];
		if(grid[x][y] == '#') dfs(x,y); 
	}
}
 
int main()
{
	cin>>n>>m;
	for(int i=1; i<=n; i++)	{
		scanf("%s",grid[i]+1);
		for(int j=1; j<=m; j++)
			if(grid[i][j] == '#')    r[i]++,c[j]++;
	}
	
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
			if(r[i] == 0 && c[j] == 0)
				st[i][j] = 1;
				
	for(int i=1; i<=n; i++)
	{
		int cnt = 0;//条件1 
		for(int j=1; j<=m; j++)
		    if(st[i][j]) cnt++;
		    
		if(!cnt && !r[i]) {
			puts("-1");
			return 0;
		}
		
		int num = r[i];//条件3
		for(int j=1; j<=m; j++) {
			if(grid[i][j] == '.' && num && num != r[i])	{
				puts("-1");
				return 0;
			}
			else if(grid[i][j] == '#') num--;
		}
	}
	
	for(int j=1; j<=m; j++)//对每一列做同样判断 
	{
		int cnt = 0;
		for(int i=1; i<=n; i++)
			if(st[i][j]) cnt++;
		
		if(!cnt && !c[j]) {
			puts("-1");
			return 0;
		}
		int num = c[j];
		for(int i=1; i<=n; i++)	{
			if(grid[i][j] == '.' && num && num != c[j])	{
				puts("-1");
				return 0;
			}
			else if(grid[i][j] == '#') num--;
		}		
	}
	
	int ans = 0;//求连通块个数 
	for(int i=1; i<=n; i++)	{
		for(int j=1; j<=m; j++)	{
			if(grid[i][j] == '#') 	{
				ans++;
				dfs(i,j);
			}
		}
	}
	
	cout<<ans;
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

米莱虾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值