所有的题目在这里<---
待补...
Problem A. HDU6264:Super-palindrome
题意:
题目定义了一个超级回文串,这个串满足:它的任一奇数长度的串都是回文串。
现在给你一个字符串,问你把它变成超级回文串需要多少次操作。每次操作可以把一个字符变成其他任一字符。
题解:
显然,一个串只有符合 整个串奇数位字符都相同,偶数位字符都相同,奇数位偶数位字符不一定要相同(包含了字符全相同的情况)时满足超级回文。
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 100+10; const int INF = 1e9+10; const ll mod = 998244353; int main(){ int T; scanf("%d",&T); for (int t = 1; t <= T; ++t) { string s; cin >> s; int a1[300]={0},a2[300]={0}; int l = s.length(),num1=0,num2=0; for (int i = 0; i < l; ++i) { if (i%2) num2 = max(num2,++a2[s[i]]); else num1 = max(num1,++a1[s[i]]); } printf("%d\n",(l/2-num1)+(l-l/2-num2)); } return 0; }
Problem C.HDU6266:Hakase and Nano
题意:
有n堆石子,每次可以选择任意一堆从中取至少一个石子,谁最后取完谁赢。
Hakase取两次,Nano取一次,两个人轮流取。问 Hakase是否能赢。
题解:
一堆石子如果只有一个,那么一次就取走了一堆,堆数减少;否则这一堆可以有剩余,堆数可以不变。
当 Hakase先取石子时,只有在每堆石子数量都为1且堆数是3的倍数时 Hakase会输,其余情况都会赢。
当 Nano先取石子时,Nano拿了第一次之后,就相当于成了Hakase先手。所以要使Hakase输需要使Nano拿了第一次之后每堆石子数量都为1且剩下的堆数是三的倍数,否则Hakase赢。这时有3种情况:
1.每堆石子都为1,且 堆数-1 是3的倍数。
2.只有一堆石子数量不为1,Nano将这堆石子全拿走,剩下 n-1堆石子数量全为1,且 n-1 是3的倍数。
3.只有一堆石子数量不为1,Nano将这堆石子剩一个,剩下 n 堆石子数量全为1,且 n 是3的倍数。
只有以上4种情况输出No,否则都是Yes。判断一下就行了。
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 100+10; const int INF = 1e9+10; const ll mod = 998244353; int main(){ int T,n,d,x; scanf("%d",&T); while (T--){ int num = 0; scanf("%d%d",&n,&d); for (int i = 0; i < n; ++i) { scanf("%d",&x); if (x == 1) num++; } bool fg = 1; if (n == num) { num %= 3; if (d == 1 && !num) fg = 0; else if (d == 2 && num == 1) fg = 0; } else if (n == num+1) { if (d == 2&&((n%3)==0||(num%3)==0)) fg = 0; } printf("%s\n",fg?"Yes":"No"); } return 0; }
Problem J. HDU6273:Master of GCD
题意:
一开始有n个全为1的数,每次操作你选择一个区间[l,r]和一个x,将这个区间内的每个数更新为乘以x之后的值,x只能是2或者3。问m次操作之后,所有数的最大公约数是多少。
题解:
一开始所有数都为1,然后对每个区间的数进行乘法运算,那么所有数的最大公约数就是他们乘的同一个数的最小次方的乘积。
例如:假设3个1,第一个乘了2次2和3次3,第二一个乘了3次2和2次3,第三个乘了4次2和1次3。那么他们的最大公约数为2的2次方与3的1次方的乘积。
那么我们只需要记录一下每个数乘了几次2和3就行了。一开始用的树状数组,后来发现可以直接用前缀和。算结果时用快速幂取模即可。
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e5+10; const int INF = 1e9+10; const ll mod = 998244353; ll num2[N],num3[N]; int T,n,m; int lowbit(int x){ return x&(-x); } void update(int id,ll *a, ll x) { while (id <= n) { a[id] +=x; id += lowbit(id); } } ll query(int id, ll *a) { ll r = 0; while (id > 0) { r += a[id]; id -= lowbit(id); } return r; } ll pq(ll a, ll b) { ll r = 1; while (b) { if (b&1) r = (r*a) % mod; a = (a*a) % mod; b>>=1; } return r; } int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); memset(num2,0,sizeof(num2)); memset(num3,0, sizeof(num3)); for (int i = 0; i < m; ++i) { int l,r,x; scanf("%d%d%d",&l,&r,&x); if (x == 2){ update(l,num2,1); update(r+1,num2,-1); }else { update(l,num3,1); update(r+1,num3,-1); } } ll n2 = query(1,num2),n3 = query(1,num3); for (int i = 2; i <= n; i++) { n2 = min(n2,query(i,num2)); n3 = min(n3,query(i,num3)); } printf("%lld\n",(pq(2,n2)*pq(3,n3))%mod); } return 0; }
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 100000+10; const int INF = 1e9+10; const ll mod = 998244353; int a[2][N]; ll pq(ll a, ll b){ ll ans = 1; while (b) { if (b&1) ans = (ans * a) % mod; a = (a * a) % mod; b >>= 1; } return ans; } int main() { int T,n,m; scanf("%d",&T); while (T--){ scanf("%d%d",&n,&m); memset(a,0,sizeof(a)); for (int i = 0; i < m; ++i) { int l,r,x; scanf("%d%d%d",&l,&r,&x); a[x-2][l]++; a[x-2][r+1]--; } ll n2, n3, sum2 , sum3; n2 = sum2 = a[0][1]; n3 = sum3 = a[1][1]; for (int i = 2; i <= n; ++i) { sum2 += a[0][i]; n2 = min(sum2,n2); sum3 += a[1][i]; n3 = min(sum3,n3); } printf("%lld\n",(pq(2,n2) * pq(3,n3))%mod); } return 0; }