Codeforces Round #654 (Div. 2) - 划水
Codeforces Round #654 (Div. 2)
https://codeforces.com/contest/1371
A. Magical Sticks
题解
题意为给出1、2、3……、n这样一个序列,通过选出两个数a、b,将a+b加入序列中并删除a和b,求出可以得到的最大的相同数个数。
因为1+(n-1)=2+(n-2)=……=(n-1)/2+(n+1)/2=n,
当n为奇数时,正好有(n-1)/2个,当n为偶数时,因为(n-1)/2=(n+1)/2,所以只有n/2-1个。
Code
#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
const int N=5007;
const ll mod=998244353;
int main(){
IO;
int t=1;
cin>>t;
while(t--){
int n,m;
cin>>n;
cout<<(n+1)/2<<endl;
}
return 0;
}
B. Magical Calendar
题解
当n=1时只有1种情况。
当n!=1时考虑n和k的关系:
- n>k,此时有k种情况,在第几行是等价的所以只考虑列,起点位置可以从第1列取到第k列。
- n<=k,此时不能将连续的n天分割在两行(类似于例子中给出的),其他情况都是1种情况。
因为1=<k<=r,判断n与r的关系:
- n>r,此时k无论如何取值都满足n>k,则答案为:\(\sum_1^r\)k,即(1+r)*r/2;
- n>=r,此时当k取值为k<n时,仍满足n>k,当k>=n时,答案为1,相加即可:\(\sum_1^m\)k+1,m=n-1,即(n-1)*n/2+1;
Code
#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
const int N=5007;
const ll mod=998244353;
int main(){
IO;
int t=1;
cin>>t;
while(t--){
ll n,r;
cin>>n>>r;
if(n==1){
cout<<1<<endl;
continue;
}
if(n>r){
cout<<(1+r)*r/2<<endl;
}
else if(n==r){
cout<<(r-1)*r/2+1<<endl;
}
else{
cout<<(n-1)*n/2+1<<endl;
}
}
return 0;
}
C. A Cookie for You
题解
题意为有两类客人,两种食物,当其中一种食物数量严格大于另一种时,第一类客人会吃多的食物,第二类会吃少的,否则可以随便吃,一次吃一个。询问给出的条件是否可以满足所有客人。
首先如果食物数量小于客人数量则不可能满足。
考虑最优情况应该是两类食物数量一样时,此时第一类和第二类客人可以轮流吃。
所以首先用第一类客人将两类食物尽量处理成数量相同的情况,处理后
- 如果两类食物数量相同,
若第一类客人数量大于等于第二类客人一定可以满足题意(第一类客人在任何情况下都可以吃食物);
若第二类客人数量多,并且数量大于任一食物数量则无法满足客人,否则可以满足。 - 如果两类食物不相等
此时第一类客人数量为0,并且第二类客人只能吃一类食物,判断食物数量和客人数量即可。
Code
#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
const int N=5007;
const ll mod=998244353;
int main(){
IO;
int t=1;
cin>>t;
while(t--){
ll a,b,n,m;
cin>>a>>b>>n>>m;
if(a+b<n+m){
cout<<"No"<<endl;
continue;
}
if(a<b)swap(a,b);
ll k=min(a-b,n);
n-=k;
a-=k;
if(a==b){
if(n>=m)cout<<"Yes"<<endl;
else {
a-=n;
m-=n;
if(m>a)cout<<"No"<<endl;
else cout<<"Yes"<<endl;
}
}else{
if(m>b)cout<<"No"<<endl;
else cout<<"Yes"<<endl;
}
}
return 0;
}
D. Grid-00100
题解
题意为给出矩阵的维数n,和矩阵元素(为0或1)的和k,求出 每行求和的最大值与最小值差值的平方 与 每列求和的最大值与最小值差值的平方之和 最小的矩阵。
考虑最优情况,当n=k时,此时只需要将主对角线上的元素设为1即可,答案为0.
所以依此类推,当k%n=0时,将每行和设为k/n,总存在将每行和每列和都为k/n的方案,此时答案为0,方案为从主对角线开始向后k/n都置为1;
当k%n!=0时,此时只需要将前k%n多向后置一个位置即可,此时最大值比最小值大1,答案为2。
Code
#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
const int N= 1e5+7;
const ll mod=998244353;
int a[307][307];
int main(){
IO;
int t=1;
cin>>t;
while(t--){
int n,k;
memset(a,0,sizeof(a));
cin>>n>>k;
int len=k/n;
int x=k%n;
cout<<2*(x>0)<<endl;
for (int i = 0; i < x; ++i)
{
for (int j = i; j <= i+len; ++j)
{
a[i][j%n]=1;
}
}
for (int i = x; i < n; ++i)
{
for (int j = i; j < i+len; ++j)
{
a[i][j%n]=1;
}
}
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
cout<<a[i][j];
}cout<<endl;
}
}
return 0;
}
E1. Asterism (Easy Version)
思路
题意为Aoi开始有x个糖果,他有n个敌人,每i个敌人有ai个糖果,你可以通过变换敌人的次序来和Aoi进行比较糖果,如果Aoi的糖果大于等于敌人,则Aoi胜出并获得一个糖果,对于每个x的情况如果获胜的情况数不被p整除则认为是一个好的数字,输出所有的好数字。
分析x的范围,因为ai可以随意排列则从小到大排序后结果最优,x最小的情况是经过n-1轮后正好等于最大的敌人的糖果数,即x>=max(a)-(n-1),最大情况是max(a)-1,如果x>=max(a),则所有情况(n!)都可以使Aoi每轮获胜,因为n>=p,所以n!%p=0一定成立,故此时x不满足题意,所以x最大值为max(a)-1。
暴力搜x的区间找出答案即可。
判断x是否为好数时,枚举每个位置的取值情况,相乘对p取模判断最后是否为0即可。
Code
#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
const int N= 1e5+7;
const ll mod=998244353;
int a[N];
int main(){
IO;
int t=1;
//cin>>t;
while(t--){
int n,p;
cin>>n>>p;
map<int,int>mp;
for (int i = 0; i < n; ++i)
{
cin>>a[i];
mp[a[i]]++;
}sort(a,a+n);
vector<int>ans;
for (int i = max(a[n-1]-n+1,1); i < a[n-1]; ++i)
{
int sum=0,cnt=1;
for (int j = 0; j < n; ++j)
{
if(a[j]<i)sum++;
else break;
}
for (int j = i; j <= i+n-1; ++j)
{
sum+=mp[j];
cnt=cnt*sum%p;
sum--;
}if(cnt){
ans.push_back(i);
}
}cout<<ans.size()<<endl;
for(int i:ans)cout<<i<<" ";
cout<<endl;
}
return 0;
}

浙公网安备 33010602011771号