Codeforces Round #461 (Div. 2) 題解
阿新 • • 發佈:2018-02-13
產生 mat 是否 amp %d str print sin 輸出
Codeforces Round #461 (Div. 2)
Codeforces 922C
題意
給定\(n,k \le 10^{18}\),判斷是否對於所有的$ i \le k,n mod i$都是不同的
解題思路
首先\(n\ mod\ 1=0\),為了不相同\(n\ mod\ 2=1\),\(n\ mod\ 3=2\)……
即\(n\ mod\ i=i-1\),\(n+1\ mod\ i=0\)
直接暴力判斷對所有的\(i\)是否成立即可,由於階乘的增長速度很快,檢查的次數幾乎是常數
AC代碼
#include <bits/stdc++.h>
using namespace std;
long long n,k;
bool solve()
{
for (long long i=1;i<=k;i++)
if((n+1)%i)
return false;
return true;
}
int main(int argc, char const *argv[])
{
scanf("%I64d%I64d",&n,&k);
if(solve())
puts("Yes");
else
puts("No");
return 0;
}
Codeforces 922D
題意
給定若幹由\(s\)和\(h\)組成的字符串,輸出將這些字符串拼接後這樣的對的數量的最大值\(i<j,s_i=‘s‘,s_j=‘h‘\)
解題思路
對於兩個字符串\(A,B\),相應\(s,h\)的數量分別為\(s_{str},h_{str}\) ,設不算這兩個串互相產生的對對答案的貢獻的其他貢獻為\(W\),則當前對的數量為\(W+s_Ah_B\),交換後為\(W+s_Bh_A\)
因此按照\(s_{str}/h_{str}\)排序後即是最佳拼接方案,隨後計算對的數量即可
AC代碼
#include <bits/stdc++.h>
using namespace std;
const int maxn=100007;
struct node
{
string str;
long long s,h;
}noise[maxn];
int order[maxn];
bool cmp(int l,int r)
{
return noise[l].s*noise[r].h>noise[l].h*noise[r].s;
}
int main(int argc, char const *argv[])
{
int n;
scanf("%d",&n);
for (int i=0;i<n;i++) order[i]=i;
for (int i=0;i<n;i++)
{
cin>>noise[i].str;
long long s=0,h=0;
for (int j=0;j<noise[i].str.size();j++)
{
if(noise[i].str[j]==‘s‘) s++;
else if(noise[i].str[j]==‘h‘) h++;
}
noise[i].s=s;
noise[i].h=h;
}
sort(order,order+n,cmp);
long long ans=0,bs=0;
for (int i=0;i<n;i++)
for (int j=0;j<noise[order[i]].str.size();j++)
{
if(noise[order[i]].str[j]==‘h‘) ans+=bs;
else if(noise[order[i]].str[j]==‘s‘) bs++;
}
printf("%I64d\n",ans);
return 0;
}
Codeforces 922E
題意
我覺得是本題難點之一,不想寫了
思路
即狀態dp[i][k]
為經過了\(i\)個樹召喚了\(k\)個鳥剩余mana的最大值,狀態轉移方程為:
\[dp[i][j]=max(dp[i][j],min(dp[i-1][j-k]+X,W+(j-k)\times B)-cost_i\times k)\]
AC代碼
#include <bits/stdc++.h>
using namespace std;
const int maxn=1007;
long long n,w,b,x;
long long c[maxn],cost[maxn];
long long dp[maxn][10*maxn];
int main(int argc, char const *argv[])
{
scanf("%I64d%I64d%I64d%I64d",&n,&w,&b,&x);
for (int i=1;i<=n;i++) scanf("%I64d",&c[i]);
for (int i=1;i<=n;i++) scanf("%I64d",&cost[i]);
memset(dp,-1,sizeof(dp));
dp[0][0]=w;
for (int i=0;i<=n-1;i++)
{
int j=0;
while(dp[i][j]!=-1)
{
if(i>0)
dp[i+1][j]=min(max(dp[i+1][j],dp[i][j]+x),w+j*b);
else
dp[i+1][j]=min(max(dp[i+1][j],dp[i][j]),w+j*b);
for (int k=1;k<=c[i+1];k++)
{
long long nxt=min(dp[i][j]+(i>0?x:0),w+j*b)-cost[i+1]*k;
if(nxt>=0) dp[i+1][j+k]=max(dp[i+1][j+k],nxt);
}
j++;
}
}
for (int i=1;i<=10001;i++)
if(dp[n][i]<0)
{
printf("%d\n",i-1);
return 0;
}
return 0;
}
Codeforces Round #461 (Div. 2) 題解