Dashboard - Codeforces Round #779 (Div. 2) - Codeforces
https://codeforces.com/contest/1658
A. Marin and Photoshoot
思维签到,令每两个0之间的1的个数大于或者等于2即可,多就不处理,少了就加
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
#include<string>
using namespace std;
void solve()
{
int n,num=0,l=-1;
string str;
cin>>n>>str;
vector<int>ve;
for(int i=0;i<str.size();i++)
{
if(str[i]=='0')
ve.push_back(i);
}
if(ve.size()<=1)
{
cout<<"0"<<"\n";
return ;
}
for(int i=0;i<ve.size()-1;i++)
{
int kong=ve[i+1]-ve[i]-1;
if(kong<2)
num+=(2-kong);
}
cout<<num<<"\n";
return ;
}
int main()
{
int t;
cin>>t;
while(t--)
solve();
return 0;
}
B. Marin and Anti-coprime Permutation
规律题
因为有这么多的数,只有当是偶数个数时,令每一个奇数位上乘以偶数,偶数位上乘以奇数,就可以保证gcd是2,如果是奇数gcd就只能为1.所以我们枚举n个空格放n个东西,n!求出来的就是奇数,偶数位的方案数,最后求平方即可.
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
#include<string>
#define int long long
using namespace std;
void solve()
{
int n;
cin>>n;
if(n%2==1)
{
cout<<"0\n";
return ;
}
int ans=1;
for(int i=1;i<=n/2;i++)
ans=(ans*i)%998244353;
cout<<(ans*ans%998244353)<<"\n";
}
signed main()
{
int t;
cin>>t;
while(t--)
solve();
return 0;
}
C. Shinju and the Lost Permutation
当首位是该全排列的最大值时,再往前走之后的情况都只能增加1或者0,那么我们就截取所给数组为1的时候,把前一段移到后面,例如 2 3 1 2 3 4变为1 2 3 4 2 3.此时只要判断数组内只有一个1,并且相邻两数变化值<=1即可.
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
#include<string>
using namespace std;
int arr[100005];
vector<int>ve;
void solve()
{
int n,tot=1,flag=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&arr[i]);
if(arr[i]==1)
flag=1;
if(flag==1)
ve.push_back(arr[i]);
}
int sum=ve.size();
for(int i=1;i<=n-sum;i++)
ve.push_back(arr[i]);
if(ve[0]!=1)
{
cout<<"NO"<<"\n";
ve.clear();
return ;
}
for(int i=1;i<ve.size();i++)
{
if(ve[i]-ve[i-1]>1||ve[i]==1)
{
cout<<"NO"<<"\n";
ve.clear();
return ;
}
}
cout<<"YES"<<"\n";
ve.clear();
}
int main()
{
int t;
cin>>t;
while(t--)
solve();
return 0;
}
D1. 388535 (Easy Version)
可以找规律,记录所给数组每一个数的二进制位数的1的个数,在求出0到r这个区间的每个数的二进制数位的1的个数,再将这两种情况对比,不相等则需要在此位异或一个1,遍历完求这些1的和即可.
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
#include<string>
using namespace std;
int cnt1[20],cnt2[20];
int c[20];
void solve()
{
memset(cnt1,0,sizeof cnt1);
memset(cnt2,0,sizeof cnt2);
int l,r;
scanf("%d%d",&l,&r);
for(int i=l;i<=r;i++)
{
int t=i,tot=0;
while(t)
{
if(t%2==1)
cnt1[tot]++;
tot++;
t/=2;
}
}
for(int i=l;i<=r;i++)
{
int t,tot=0;
scanf("%d",&t);
while(t)
{
if(t%2==1)
cnt2[tot]++;
tot++;
t/=2;
}
}
int x=0;
for(int i=0;i<=19;i++)
{
if(cnt1[i]!=cnt2[i])
x+=c[i];
}
printf("%d\n",x);
return ;
}
int main()
{
int t;
c[0]=1;
for(int i=1;i<=19;i++)
c[i]=c[i-1]*2;
cin>>t;
while(t--)
solve();
return 0;
}