这次abc还是四个题,40分钟做了四个,由于前面三个题比较水,所以用的时间不多,第四个是忘了初始化,检查了十几分钟才发现错误,第五个拆位思想给忘了,后面去看了一下之前的那个博客才过的
A - Leap Year
题意:就是说给你一个年份,让你去判断那个年份有多少天
思路:4的倍数但是不是100的倍数是366天,400的倍数是366天,除了这两种情况都是365天
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
string s;
signed main()
{
cin>>n;
if(n%4==0&&n%100!=0)
{
cout<<366;
}
else if(n%400==0)
{
cout<<366;
}
else
cout<<365;
return 0;
}
B - Second Best
题意:求次大值的下标
因为每个数都不一样,先求出来次大值,然后数组里一个一个比对即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
string s;
int a[2005];
int maxn,cmaxn;
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]>maxn)
{
cmaxn=maxn;
maxn=a[i];
}
else if(a[i]>cmaxn)
{
cmaxn=a[i];
}
}
for(int i=1;i<=n;i++)
{
if(cmaxn==a[i])
{
cout<<i;
break;
}
}
return 0;
}
C - Transportation Expenses
思路:一眼二分答案,我去二分能够提供的最大补给不就是了
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
string s;
int a[200005];
int l,r,mid;
int ans;
int check(int x)
{
int sum=0;
for(int i=1;i<=n;i++)
{
sum+=min(x,a[i]);
if(sum>m)
return 0;
}
return 1;
}
signed main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
int l=0,r=1e9;
while(l<r)
{
mid=l+(r-l+1)/2;
if(check(mid)==1)
{
l=mid;
}
else
{
r=mid-1;
}
}
if(l==1e9)
{
cout<<"infinite"<<"\n";
return 0;
}
cout<<l<<"\n";
return 0;
}
D - AtCoder Janken 3
这题就是一个普通的动态规划,我们需要保留三种状态,而且我们要确保没一回合要么平局,要么就是获胜,反正不能输,最终确保最多获胜多少局
思路,我们的的dp数组:dp[ i ] [ j ] 表示,在第i局出 j 能够获胜的最大局数
然后写出状态转移方程即可
PS:一定要注意dp[1]的初始化,要根据第一个手势进行初始化
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
string s;
int dp[200005][5];
signed main()
{
cin>>n;
cin>>s;
if (s[0] == 'R')
{
dp[0][1] = 0;
dp[0][3] = 1;
}
else if (s[0] == 'S')
{
dp[0][1] = 1;
dp[0][2] = 0;
}
else if (s[0] == 'P')
{
dp[0][2] = 1;
dp[0][3] = 0;
}
for(int i=1;i<n;i++)
{
if(s[i]=='R')
{
dp[i][1]=max(dp[i-1][2],dp[i-1][3]);
dp[i][3]=max(dp[i-1][2],dp[i-1][1])+1;
}
if(s[i]=='S')
{
dp[i][1]=max(dp[i-1][2],dp[i-1][3])+1;
dp[i][2]=max(dp[i-1][1],dp[i-1][3]);
}
if(s[i]=='P')
{
dp[i][2]=max(dp[i-1][1],dp[i-1][3])+1;
dp[i][3]=max(dp[i-1][2],dp[i-1][1]);
}
}
cout<<max(dp[n-1][1],max(dp[n-1][2],dp[n-1][3]));
return 0;
}
E - Xor Sigma Problem
这题用到拆位的思想了,没学过的可以看看别人的博客学一下,我晚点再发拆位思想的博客
#include<bits/stdc++.h>
#define int long long
using namespace std;
int ans[20]= {0};//统计第i位,1的次数
int b[200001];
int sum[200001]= {0};//异或数组
long long res=0;
int n,a,i,len;
int maxn=-1;//统计最大位数
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>b[i];
}
for(int i=1; i<=n; i++)
{
sum[i]=sum[i-1]^b[i];
}
for(i=1; i<=n; i++)
{
a=sum[i];
len=0;
while(a)
{
len++;
if(a&1)
ans[len]++;
a=a>>1;
}
maxn=max(maxn,len);
}
for(i=1; i<=maxn; i++)
{
res+=(1LL<<(i-1))*ans[i]*(n-ans[i]);
}
for(int i=1; i<=n; i++)
{
res+=sum[i];
res-=b[i];
}
cout<<res;
return 0;
}