Codeforces Round #663 (Div. 2)
A题:https://codeforces.ml/contest/1391/problem/A
直接从1开始输出即可
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char const *argv[])
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
printf("1");
for (int i = 2; i <= n; ++i)
{
printf(" %d",i);
}
printf("\n");
}
return 0;
}
B题:https://codeforces.ml/contest/1391/problem/B
保证最后一行全为R,最后一列全为D即可
#include <bits/stdc++.h>
using namespace std;
char s;
int main(int argc, char const *argv[])
{
int t,n,m;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
int ans = 0;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
cin>>s;
if (i == n-1 && s=='D') ans++;
if (j == m-1 && s=='R') ans++;
}
}
printf("%d\n",ans);
}
return 0;
}
C题:https://codeforces.ml/contest/1391/problem/C
考虑如何构造环,当从一个数出发,出现两条边的时候,就会形成环。例如2 1 3,从1出发连接了2和3,而2,3必然有边,即只要出现一个数连两个数必然有环,也就是说要让一个排列没有环,那比这个数大的数只能在这个数的一侧。那么我们可以考虑n个数的全排列为n!再减去没有环的情况。对于每一个数而言,比他大的数只能在他的一侧,那么n个位置里,这个数只能放在两头,剩下的数同理,也即是2^(n-1)种可能。
#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9+7;
long long fastpow(long long a,long long n)
{
long long base = a;
long long res = 1;
while(n)
{
if(n&1) res = (res * base)%mod;
base = (base * base)%mod;
n>>=1;
}
return res;
}
int main(int argc, char const *argv[])
{
long long t;
scanf("%lld",&t);
long long n = 1;
long long ans = fastpow(2,t-1);
for (int i = 1; i <= t; ++i)
{
n = ((n%mod) * (i%mod))%mod;
}
long long ans2 = (n-ans+mod)%mod;
cout<<ans2<<endl;
return 0;
}
D题:https://codeforces.ml/contest/1391/problem/D
比赛的时候没有写出来,看了别人的题解才做出来的。
可以知道当n>=4的时候一定不存在,所以输出-1(题上给了m>=n,不然这题还要恶心一点)
当n==1的时候由于没有 even length square所以输出0
接下来就剩下n==2和n==3的情况了,直接暴力构造。
当n==2的时候,第一列只有4种情况:00,01,10,11,遍历这4种情况,用输入的矩阵来对比,不同则ans++,接下来遍历剩下的m-1列,每次计算一个2*2的子矩阵,如果为偶数则修改当前列的任意一个值(0变1,1变0),ans++,不断更新取最小即可。
当n==3的时候,与2同理,第一列有8种情况,依次遍历,每次计算上下两个2*2的子矩阵,如果都为奇数则continue,有一个为偶数则修改其中一个,两个都为偶数则修改中间那个,更新答案即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
int n,m;
int f[3][N],t[3][N];
char s[N];
int s2[4][2]={0,0,0,1,1,0,1,1};
int s3[8][3]={0,0,0,0,0,1,0,1,0,0,1,1,1,0,0,1,0,1,1,1,0,1,1,1};
int main(int argc, char const *argv[])
{
scanf("%d%d",&n,&m);
if (n >= 4)
{
printf("-1\n");
return 0;
}
else if (n == 1)
{
printf("0\n");
return 0;
}
for (int i = 0; i < n; ++i)
{
scanf("%s",s);
for (int j = 0; j < m; ++j)
{
f[i][j] = s[j] - '0';
}
}
if (n == 2)
{
int res = N;
for (int i = 0; i < 4; ++i)
{
int ans = 0;
for (int ii = 0; ii < n; ++ii)
{
if (f[ii][0] != s2[i][ii])
{
t[ii][0] = s2[i][ii];
ans++;
}
else t[ii][0] = f[ii][0];
}
for (int jj = 1; jj < m; ++jj)
{
t[0][jj] = f[0][jj];
t[1][jj] = f[1][jj];
int val = t[0][jj] + t[1][jj] + t[0][jj-1] + t[1][jj-1];
if (val % 2 == 0)
{
t[0][jj] = (t[0][jj] ? 0:1);
ans++;
}
}
res = min(ans,res);
}
printf("%d\n",res);
}
else
{
int res = N;
for (int i = 0; i < 8; ++i)
{
int ans = 0;
for (int ii = 0; ii < n; ++ii)
{
if (f[ii][0] != s3[i][ii])
{
t[ii][0] = s3[i][ii];
ans++;
}
else t[ii][0] = f[ii][0];
}
for (int jj = 1; jj < m; ++jj)
{
t[0][jj] = f[0][jj];
t[1][jj] = f[1][jj];
t[2][jj] = f[2][jj];
int val1 = t[0][jj] + t[1][jj] + t[0][jj-1] + t[1][jj-1];
int val2 = t[2][jj] + t[1][jj] + t[2][jj-1] + t[1][jj-1];
if (val1 % 2 == 1 && val2 % 2 == 1) continue;
if (val1 % 2)
{
t[2][jj] = (t[2][jj] ? 0:1);
ans++;
}
else if (val2 % 2)
{
t[0][jj] = (t[0][jj] ? 0:1);
ans++;
}
else
{
t[1][jj] = (t[1][jj] ? 0:1);
ans++;
}
}
res = min(ans,res);
}
printf("%d\n",res);
}
return 0;
}