A. Suborrays
题意:
输入一个长度 ,用 的数字进行随机排列。定义对于一个正整数 ,如果对于每一对 和 都满足,对于 的每个子数组,其中所有元素的 不小于该子数列中元素的个数。我们称长度为 的排列 是好的。
两个数进行位运算了,且范围是 ,那么进行位运算后的结果不会小于元素的个数。简而言之就是:无论怎么输出这个置换序列都是正确的。
AC代码:
int t;
int n,m;
int ans[N];
int main()
{
sd(t);
while (t--)
{
sd(n);
rep(i,1,n)
printf("%d%c",i,i==n?'\n':' ');
}
}
B. Fix You
题意:
给定一个 的网格传送带,每个传送带上都有一个方向为, 代表向下, 代表向右。我们可以改变传送的的方向。(只能在下右之间做调整。)其中 处为柜台,我们要使得网格传送带上的行李都能到达柜台处,求我们至少要进行多少次操作更改。
因为只有向下和向右,所以把全部的边缘给改变了就行。
AC代码:
const int N = 2010;
int t;
int n, m;
char a[200][200];
int main()
{
sd(t);
while (t--)
{
sdd(n, m);
rep(i, 1, n)
{
rep(j, 1, m)
{
cin >> a[i][j];
}
}
int ans = 0;
rep(i, 1, n - 1)
{
if (a[i][m] == 'R')
ans++;
}
rep(j, 1, m - 1)
{
if (a[n][j] == 'D')
ans++;
}
pd(ans);
}
return 0;
}
C. Cyclic Permutations
题意:
对于所有长度为 的排列,找出有多少个满足其中存在至少一个简单环。(对于排列中的每个值 ,和其左右两边第一个大于它的 连一条无向边)
满足条件的排列数等于总排列数-不满足条件的排列数。
而不满足条件的排列数通过找规律:
如
时:
不满足条件的排列有:
一共八个,但可以分为
组。一位第
,第
,第
,第
个排列,分别是
的。那么只分析第
个排列。我们发现。其实规律只与排列中的最小数字
和最大数字
的位置有关。
如将排列写成
形式。则
与
之间的数字必须升序,
后的数字必须降序。那么我们只需考虑
与
之间数字的个数即可。
而 与 之间数字的个数取值范围是 ,假如 与 之间放 个数 ,又因为这 个数一定是升序,所以是组合数 。
那么可见,不满足条件的排列数为
。
而全排列个数为
,所以答案就是
。
AC代码:
ll qpow(ll x, ll n, ll mod)
{
ll res = 1;
while (n)
{
if (n & 1)
res = (res * x) % mod;
x = x * x % mod, n >>= 1;
}
return res;
}
const int N = 2010;
const int mod = 1e9 + 7;
int t;
ll n, m;
char a[200][200];
int main()
{
sld(n);
ll ans = 1;
rep(i, 1, n)
ans = (ans * i) % mod;
ans = (ans - qpow(2, n - 1, mod)) % mod;
pld((ans % mod + mod) % mod);
return 0;
}
D. 505
题意:
给定一个 的 矩阵,求至少要改多少个元素,使得每个边长为偶数的正方形都包含奇数个 。或无解。
若存在边长为 的正方形,肯定是无解的。因为将它拆成 个边长为 的正方形,奇+奇+奇+奇=偶。
-
:显然答案为 ;
-
:每列的 的数量的奇偶性显然只有 和 两种,都算一下比个大小即可;
-
:每列上下两个 矩阵的1的数量的奇偶性显然只有
四种,易证每列最多修改 次,都算一下比个大小即可。
AC代码:
const int N = 1000000;
int n, m;
vector<string> v;
bool a[4][N + 1];
int main()
{
sdd(n, m);
if (n >= 4 && m >= 4)
{
puts("-1");
return 0;
}
rep(i, 1, n)
{
string a;
cin >> a;
v.pb(a);
}
if (n >= 4)
{
rep(i, 1, n)
{
rep(j, 1, m)
a[j][i] = v[i - 1][j - 1] ^ 48;
}
swap(n, m);
}
else
{
rep(i, 1, n)
{
rep(j, 1, m)
a[i][j] = v[i - 1][j - 1] ^ 48;
}
}
if (n == 1)
puts("0");
else if (n == 2)
{
int ans = 0;
rep(i, 1, m)
{
ans += (a[1][i] ^ a[2][i]) == (i & 1);
}
pd(min(ans, m - ans));
}
else
{
int ans1 = 0, ans2 = 0, ans3 = 0, ans4 = 0;
rep(i, 1, m)
ans1 += (a[1][i] ^ a[2][i]) != (i & 1) || (a[2][i] ^ a[3][i]) != (i & 1);
rep(i, 1, m)
ans2 += (a[1][i] ^ a[2][i]) == (i & 1) || (a[2][i] ^ a[3][i]) != (i & 1);
rep(i, 1, m)
ans3 += (a[1][i] ^ a[2][i]) != (i & 1) || (a[2][i] ^ a[3][i]) == (i & 1);
rep(i, 1, m)
ans4 += (a[1][i] ^ a[2][i]) == (i & 1) || (a[2][i] ^ a[3][i]) == (i & 1);
pd(min(min(ans1, ans2), min(ans3, ans4)));
}
return 0;
}