问题 A: 马克的字符串
时间限制: 1 Sec 内存限制: 256 MB题目描述
定义一个字符串满足'MK'性质当且仅当它修改其中不超过k个字符后是回文串。给你一个字符串,问它有多少非空子串满足'MK'性质。
输入
输入的第一行包含一个字符串s
输入的第二行包含一个整数k
输出
输出的第一行包含一个整数,为满足'MK'性质的字串数量。
样例输入
Aab 1
样例输出
6
提示
【样例说明】
每一个字串都是回文串或修改一个字母后是回文串
【数据规模与约定】
对于30%的数据:k=0
对于100% 的数据:字符串长度 1<=l<=100,0<=k<=50
题解:n^3暴力,开始跑了个manacher,结果WA了,至今迷
#include<bits/stdc++.h> using namespace std; char str[208]; int k; bool check(int i, int j){ int cnt = 0; while(i <= j){ if(str[i] != str[j])cnt ++; if(cnt > k)return 0; i++, j--; } return 1; } int main(){ scanf("%s", str); scanf("%d", &k); int ans = 0; int len = strlen(str); for(int i = 0; i < len; i++) for(int j = i; j < len; j++) ans += check(i, j); printf("%d",ans); }
问题 B: 马克家的书
时间限制: 1 Sec 内存限制: 256 MB题目描述
马克家收藏了一套书,这套书叫《OIER故事集》,这套书有n本,每本书有一个编号,从1号到n号。
马克把这些书按照编号从小到大,从上往下摞成一摞。马克对这套书很珍视,不允许其他人动。
有一天一格到马克家玩,马克因为和妹子约会,就让一格自己呆在家里。一格因为对这套书非常好奇,偷偷的看了一下,结果发现书中竟然有ljs和commonc的故事。一格看的入了迷,结果把一摞书的顺序弄乱了。
眼看着马克就要回来了,一格需要把书恢复到原状,由于每本书都比较重,所以一格能做的操作是把一本书从书堆中抽出来,然后把这本书放到书堆的顶部。
给你打乱的书的顺序,你能帮一格算算最少需要几次上述操作,才能恢复书的顺序。
输入
第一行包含一格正整数T(T<=10),表示数据组数。
对于每组数据,第一行为一格整数n。
接下来的一行有n个用空格分开的正整数,表示一格打乱后的书的顺序,从上到下。
输出
对于每组数据,输出一行一个整数,表示一格最少经过几次操作才能恢复书的顺序。
样例输入
2
4
4 1 2 3
5
1 2 3 4 5
样例输出
3
0
提示
【样例说明】
样对于第一组数据,我们先把3号书放在最上面,接着操作2号书,最后操作1号书,(4,1,2,3)—(3,4,1,2)—(2,3,4,1)—(1,2,3,4)这样就有序了。
对于第二组数据,已经有序就不需要挪了。
【数据规模与约定】
对于 50% 的数据满足 n<=10
对于 80%的数据满足 n<=1000
对于 100% 的数据满足 n<=100000
题解:智力题,从后往前扫,递减序列,其他的最少移动一次
#include<bits/stdc++.h> using namespace std; const int maxn = 100005; int a[maxn]; int main(){ int t; scanf("%d",&t); while(t--){ int n; scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); int p = n, cnt = 0; for(int i = n; i >= 1; i--) if(a[i] == p)p--, cnt++; printf("%d\n",n - cnt); } }
问题 C: 马克的幸运数
时间限制: 1 Sec 内存限制: 256 MB
题目描述
马克和同学们玩卡牌游戏。一共有n张卡牌,每张卡牌上有一个数Ai,每次可以从中选出k张卡牌。一种选取方案的幸运数为这k张卡牌上数的异或和。马克想知道所有选取方案的幸运数之和除以998244353的余数。
输入
第一行有两个整数n和k。
第二行有n个整数,表示序列A。
输出
一行,一个整数,表示答案。
样例输入
3 2 1 2 3
样例输出
6
提示
【样例说明】
样例1幸运值之和为(1 ⊕ 2) + (1 ⊕ 3) + (2 ⊕ 3) = 6
【样例输入2】
10 5
123 456 789 987 654 321 101 202 303 404
【样例输出2】
130776
【数据规模与约定】
对于30%的数据满足,1<=n<=20
对于另30%的数据满足,1<=n<=100,0<Ai<=1024
对于80%的数据满足,1<=n<=2000
对于100%的数据满足,1<=n<=100000,0<Ai<2^31,1<=k<=n
题解:亦或和拆位,统计每位有1的个数,只有选奇数个才有贡献,然后方枚举选1多少个,选0多少个,乘法原理,注意特判不要超过k
#include<bits/stdc++.h> using namespace std; const int maxn = 100005; #define ll long long ll a[maxn], fac[maxn], infac[maxn]; const ll p = 998244353; ll exgcd(ll a, ll b, ll &x, ll &y){ if(b == 0){ x = 1; y = 0; return a; } ll x0, y0; ll d = exgcd(b, a % b, x0, y0); x = y0; y = x0 - (a / b ) * y0; return d; } ll inv(ll a){ ll x, y; exgcd(a, p, x, y); return (x % p + p) % p; } int main(){ int n, k; fac[0] = 1; infac[0]= 1; ll ans = 0; scanf("%d%d", &n, &k); for(int i = 1; i <= n; i++){ scanf("%lld", &a[i]); fac[i] = fac[i-1] * i % p; infac[i] = inv(fac[i]); } long long an=1; for(int i = 0; i <= 31; i++){ int sum = 0; for(int j = 1; j <= n; j++) if(a[j] & (1<<i) )sum++; int siz = min(k, sum); for(int j = 1; j <= siz; j+=2) if (k - j <= n-sum ) ans = ( ans + ( (1ll<<i) % p * (fac[sum] * infac[j] % p * infac[sum-j] % p ) % p * (fac[n - sum] * infac[n - sum - k + j] % p * infac[k - j] % p) ) )% p; } printf("%lld\n", ans); }
问题 D: 马克的达人秀
时间限制: 1 Sec 内存限制: 256 MB
题目描述
马克要带着他的N个oier,方便起见编号为1…N,到oi展览会上去,参加每年的达人秀!他的第i个oier体重为wi,才艺水平为ti,两者都是整数。在到达时,马克就被今年达人秀的新规则吓到了:
(一)参加比赛的一组oier必须总重量至少为W(这是为了确保是强大的队伍在比赛,而不仅是强大的某个oier),并且
(二)总才艺值与总重量的比值最大的一组获得胜利。
马克注意到他的所有oier的总重量不小于W,所以他能够派出符合规则(一)的队伍。帮助他确定这样的队伍中能够达到的最佳的才艺与重量的比值。
输入
输入的第一行包含N和W。下面N行,每行用两个整数wi和ti描述了一个oier。
输出
请求出马克用一组总重量最少为W的oier最大可能达到的总才艺值与总重量的比值。
如果你的答案是A,输出1000*A向下取整的值,以使得输出是整数
(当问题中的数不是一个整数的时候,向下取整操作在向下舍入到整数的时候去除所有小数部分)。
样例输入
3 15 20 21 10 11 30 31
样例输出
1066
提示
在这个例子中,总体来看最佳的才艺与重量的比值应该是仅用一个才艺值为11、重量为10的oier,但是由于我们需要至少15单位的重量,最优解最终为使用这头奶牛加上才艺值为21、重量为20的oier。这样的话才艺与重量的比值为(11+21)/(10+20)=32/30=1.0666666…,乘以1000向下取整之后得到1066。
【数据规模与约定】
对于20%的数据满足,1<=n<=20
对于40%的数据满足,1<=n<=50,输出答案保证小于23333
对于100%的数据满足,1≤N≤250,1≤W≤1000,1≤wi≤10^6,1≤ti≤10^3
保证数据有梯度
题解:dp,01背包, f[i][j]表示达到才艺值为i最少花的体力, 答案就在dp[0~sum][w] (w >W)中
#include<bits/stdc++.h> using namespace std; const int maxn = 300, maxm = 300005, inf = 1000000008; int N, W; const double eps = 1e-6; struct cow{ int t, w; double val; }c[maxn]; int dp[2][maxm]; int main(){ scanf("%d%d", &N, &W); int sum = 0; double ans = 0; for(int i = 1; i <= N; i++) scanf("%d%d", &c[i].w, &c[i].t), sum += c[i].t; int u = 0; for(int i = 1; i <= sum; i++) dp[u][i] = inf; dp[0][0] = 0; for(int i = 1; i <= N; i++){ u ^= 1; for(int j = 0; j <= sum; j++)dp[u][j] = dp[u^1][j]; for(int j = c[i].t; j <= sum; j++)dp[u][j] = min(dp[u][j], dp[u^1][j - c[i].t] + c[i].w); /*for(int j = 0; j <= sum; j++)if(dp[u][j] != inf){ printf("i = %d j = %d dp = %d\n",i,j,dp[u][j]); }*/ } for(int i = 0; i <= sum; i++) if(dp[u][i] >= W) ans = max(ans, 1.0 * i / dp[u][i]); printf("%d\n", (int) floor(ans*1000)); }
第一天考崩了,差距巨大,后面怎么也追不上去,奠定我在联训悲惨的基调