Educational Codeforces Round 170 (Rated for Div 2)解题记录
Two Screens :
签到题
code:
#include <bits/stdc++.h>
using namespace std;
int T;
string s1,s2;
int len1,len2;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> T;
while(T--)
{
cin >> s1;
cin >> s2;
len1 = s1.length();
len2 = s2.length();
if(len1 > len2)
{
swap(s1,s2);
swap(len1,len2);
}
int cnt = 0,flag = 1;
for(int i = 0;i < len1;i++)
{
if(s1[i] == s2[i] && flag == 1)
{
cnt ++;
}
else
{
flag = 0;
break;
}
}
cout << min(len1 + (len2 - cnt) + 1,len1 + len2) << endl;
}
return 0;
}
### Binomial Coefficients, Kind Of
性质题,手玩一下不难发现\(C[n][k] = 2^k\)
code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 10;
const int MOD = 1e9 + 7;
int T;
struct edge
{
int n;
int m;
}e[N];
int qpow(int t)
{
int ret = 1;
int g = 2;
while(t)
{
if(t % 2 == 1)
ret *= g,ret %= MOD;
t /= 2;
g *= g;
g %= MOD;
}
return ret % MOD;
}
signed main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> T;
for(int i = 1;i <= T;i++)
cin >> e[i].n;
for(int i = 1;i <= T;i++)
cin >> e[i].m;
for(int i = 1;i <= T;i++)
{
cout << qpow(e[i].m) << endl;
}
return 0;
}
New Game
模拟题,暴力模拟找最大值即可
#include <bits/stdc++.h>
using namespace std;
const int N = 200000 + 10;
int T;
int n,k;
int f[N];
queue <int> q;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> T;
while(T--)
{
cin >> n >> k;
for(int i = 1;i <= n;i++)
cin >> f[i];
sort(f + 1,f + n + 1);
int ans = 1;
int sum = 0,tsum = 0,nowk = 1;
f[0] = f[1];
for(int i = 1;i <= n;i++)
{
if(f[i] == f[i - 1])
{
tsum ++;
sum ++;
}
else if(f[i] == f[i - 1] + 1)
{
if(nowk < k)
{
q.push(tsum);
tsum = 1;
nowk++;
sum++;
}
else
{
q.push(tsum);
int u = q.front();
ans = max(ans,sum);
q.pop();
sum -= u;
sum++;
tsum = 1;
}
}
else
{
ans = max(ans,sum);
while(!q.empty())q.pop();
sum = 1;
tsum = 1;
nowk = 1;
}
}
ans = max(ans,sum);
cout << ans << endl;
while(!q.empty())q.pop();
}
return 0;
}
Attribute Checks
dp题,设\(dp[i][j]\)为对于第i个可以加分的机会时,j分加给了力量,此时可以通过的最多测试数,每个\(dp[i][j]\)均可由\(dp[i - 1][j - 1],dp[i-1][j]\) 转移而来,再用一个树状数组维护一下两个加分机会之间的测试需要分数即可,(智力与力量分别排序也是可以做的)。注意:一定要注意树状数组的最大范围
#include <bits/stdc++.h>
using namespace std;
const int N = 2e6 + 10;
int n,m;
int f[N];
int dp[5010][5010];
int tre1[5010];
int lowbit(int x)
{
return x & (-x);
}
int query1(int x)
{
int ret = 0;
for(int i = x;i;i -= lowbit(i))
ret += tre1[i];
return ret;
}
void update1(int pos,int val)
{
for(int i = pos;i <= m;i += lowbit(i))
tre1[i] += val;
}
int tre2[5010];
int query2(int x)
{
int ret = 0;
for(int i = x;i;i -= lowbit(i))
ret += tre2[i];
return ret;
}
void update2(int pos,int val)
{
for(int i = pos;i <= m;i += lowbit(i))
tre2[i] += val;
}
int ans = 0;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> n >> m;
for(int i = 1;i <= n;i++)
cin >> f[i];
int cnt = 0;
for(int i = 1;i <= n;i++)
{
if(f[i] != 0)
{
if(f[i] < 0)
update1(-f[i],1);
if(f[i] > 0)
update2(f[i],1);
}
else if(f[i] == 0)
{
if(cnt == 0)
{
++cnt;
memset(tre1,0,sizeof(tre1));
memset(tre2,0,sizeof(tre2));
continue;
}
dp[cnt][0] = dp[cnt - 1][0] + query1(cnt);
for(int k = 1;k <= cnt;k++)
{
int tt = query2(k) + query1(cnt - k);
dp[cnt][k] = max(dp[cnt - 1][k],dp[cnt - 1][k - 1]);
dp[cnt][k] += tt;
ans = max(ans,dp[cnt][k]);
}
++cnt;
memset(tre1,0,sizeof(tre1));
memset(tre2,0,sizeof(tre2));
}
}
dp[cnt][0] = dp[cnt - 1][0] + query1(cnt);
for(int k = 1;k <= cnt;k++)
{
int tt = query2(k) + query1(cnt - k);
dp[cnt][k] = max(dp[cnt - 1][k],dp[cnt - 1][k - 1]);
dp[cnt][k] += tt;
}
for(int i = 0;i <= cnt;i++)
ans = max(ans,dp[cnt][i]);
cout << ans;
return 0;
}
Card Game
又是一道dp题,设\(dp[i][j]\)为分到花色为i时,总共需要j张多出来的花色1来填补的方案数,其中,先预处理\(val[i][j]\)为对于同一个花色,从小到大分到数值\(i\)时,需要\(j\)个花色1来填补的方案数,可以通过dp处理出val数组,由此,也可以通过dp将dp数组处理出(对于\(dp[i][j]\),对于该花色,枚举用了k个花色1来填补,由此列出转移方程)。最后,由于对于\(val[i][j]\),可以考虑将每一种方案进行反转,即原先分给玩家1的分给玩家2,原先分给玩家2的分给玩家1,再对一一对应的那几组牌再进行分配,那么方案便由需要j个花色1来进行填补变为了多出了j个花色1可以使用,\(val[i][j]\)也变为了对于花色1,多出了j个花色1可供使用的方案数,那么最后直接统计答案即可。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 510;
const int MOD = 998244353;
int n,m;
int val[N][N];
int dp[N][N];
signed main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> n >> m;
val[1][0] = 0;
val[1][1] = 1;
for(int i = 2;i <= m;i++)
{
val[i][0] = val[i - 1][1];
for(int k = 1;k <= i;k++)
{
val[i][k] = val[i - 1][k + 1] + val[i - 1][k - 1];
val[i][k] %= MOD;
}
}
if(n == 1)
{
cout << val[m][0];
return 0;
}
for(int i = 2;i <= n;i++)
{
if(i == 2)
{
for(int k = m;k >= 0;k--)
{
dp[i][k] = val[m][k];
}
continue;
}
for(int k = m;k >= 0;k--)
{
for(int j = min(m,k);j >= 0;j -= 2)
{
dp[i][k] += dp[i - 1][k - j] * val[m][j];
dp[i][k] %= MOD;
}
}
}
int ans = 0;
for(int i = 0;i <= m;i++)
ans += val[m][i] * dp[n][i],ans %= MOD;
cout << ans;
return 0;
}
浙公网安备 33010602011771号