AtCoder Beginner Contest 167
A 直接判断字符串就可以了,字符串是可以比较大小的。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
string a,b;
cin>>a>>b;
if(a==b.substr(0,b.size()-1)) puts("Yes");
else puts("No");
return 0;
}
B 直接计算就好了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int a,b,c,k;
cin>>a>>b>>c>>k;
if(k<=a+b) cout<<min(k,a);
else cout<<a-(k-a-b);
return 0;
}
C 刚看题像是背包,可是不会写,数据范围足够小,直接暴力枚举每一种选择状态(用状压表示),计算每一种算法是否都能达到x,不能就continue,能就取最小值。
时间复杂度 O(2^nnm)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=15;
int n,m,x,c[N],a[N][N];
int f[1<<N][N];
int main()
{
cin>>n>>m>>x;
for(int i=1;i<=n;i++)
{
cin>>c[i];
for(int j=1;j<=m;j++)
cin>>a[i][j];
}
int ans=0x3f3f3f3f;
for(int i=1;i<(1<<n);i++)//共有2^n种选择方式,都不选可以忽略
{
int res[15];
for(int j=1;j<=m;j++) res[j]=0;
for(int j=0;j<n;j++)
{
if(i&(1<<j))//判断当前状态下,第j+1本书是否被选择
{
for(int k=1;k<=m;k++)//被选择后把这本书的贡献加进去
res[k]+=a[j+1][k];
}
}
bool flag=1;
int cnt=0;
for(int j=1;j<=m;j++)
if(res[j]<x)
{
flag=0;
break;
}
if(flag)
{
for(int j=0;j<n;j++)
if(i&(1<<j))
cnt+=c[j+1];
ans=min(ans,cnt);
}
}
if(ans==0x3f3f3f3f) puts("-1");
else
cout<<ans;
return 0;
}
D 首先要把环路找出来,当路径中的下一个点已经被走过了,那环路就确定了(环路的起点不一定是1)。根据题意环路是一定存在的。判断k是在环路的内部还是外部再分情况处理即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200010;
int n,m,a[N];
ll k;
bool st[N];
int main()
{
cin>>n>>k;
k++;//把点1当做起点了,k就向后推一位
for(int i=1;i<=n;i++) cin>>a[i];
vector<int> ve;
int pos=1;
while(!st[pos])
{
ve.push_back(pos);
st[pos]=1;
pos=a[pos];
}
int l,len;环路起点的位置,环路的长度
for(int i=0;i<ve.size();i++)
if(ve[i]==pos)
{
l=i;
break;
}
len=ve.size()-l;
if(k>ve.size())
{
k-=ve.size();
k%=len;
if(k==0) cout<<ve[ve.size()-1];
else
cout<<ve[k+l-1];
}
else cout<<ve[k-1];
return 0;
}