A.
直接拿个deque模拟一下就完了
#include<cstdio>
#include<iostream>
#include<deque>
#include<algorithm>
using namespace std;
int main()
{
int n,k,i,j,cnt=0;
cin>>n>>k;
deque<int>que;
for(i=1;i<=n;i++){
cin>>j;que.push_back(j);
}
while(!que.empty()&&que.back()<=k){
cnt++;que.pop_back();
}
while(!que.empty()&&que.front()<=k){
cnt++;que.pop_front();
}
cout<<cnt<<endl;
return 0;
}
B.
把所有因数从小到大排一遍再反着reverse一下就行
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
int main()
{
int n,i,j,k;
//string str;
char str[105];
cin>>n>>str+1;
vector<int>div;
for(i=1;i<=n;i++){
if(n%i==0)
div.push_back(i);
}
for(auto a:div){
reverse(str+1,str+1+a);
}
cout<<str+1<<endl;
return 0;
}
C.
从a~z依次统计每个字母出现的次数,从a~z依次减去直到满足要求即可。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int cnt[30];
int main()
{
int n,k,i,j;string str,str1;
cin>>n>>k>>str;
for(auto a:str)
cnt[a-'a'+1]++;
for(i=1;i<=26;i++){
if(k<cnt[i])break;
k-=cnt[i];
}
cnt[i]=k;i++;
for(;i<=26;i++)cnt[i]=0;
for(auto a:str){
if(cnt[a-'a'+1]){
cnt[a-'a'+1]--;
}
else
str1+=a;
}
cout<<str1<<endl;
return 0;
}
D.
题目有一个简单而且感觉上很对事实上也很对但是严格证明并不容易的想法,就是对于每个数,把他移到最近的能放下他的位置,最终得出的一定是最优解。于是从前往后每读取一个数,就找一个最近的位置把他给放进去…
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=2e5+5;
int next1[N],cnt[N],a[N],limit;
int getpos(int x)//找到最近的能放这个余数的位置
{
if(cnt[x]<limit)return x;//如果这个余数位置本身没满那么不需要进行更改
return next1[x]=getpos(next1[x]);//更新当前余数的下一个可放位置
}
int main()
{
int n,m,i,j;
cin>>n>>m;
for(i=1;i<=n;i++)scanf("%d",&a[i]);
for(i=0;i<m;i++)next1[i]=(i+1)%m;//初始每个余数的下一个可放位置就是余数+1的位置
limit=n/m;long long ans=0;//记得ll!!!否则会爆
for(i=1;i<=n;i++){
int t=a[i]%m;
int x=getpos(t);
cnt[x]++;
ans+=(x-t+m)%m;
a[i]+=(x-t+m)%m;
}
cout<<ans<<endl;
for(i=1;i<=n;i++)
printf("%d%c",a[i],i==n?'\n':' ');
return 0;
}
E.
这是个艹蛋的题目…wa了一晚上的test31…
其实,很容易发现我们想干的事情是找出每一组的城市,使得同一组中的城市都可以从1个点出发而到达本组中的所有点,并且总组数最少。或者,通俗地说,类似于找出所有链的起始点,从s连边至这个点即可(但是这种说法并不准确,因为还会有独立环)。
那么,我们可以走一遍dfs,对于每个点,如果他没有被dfs过,就以他为起点dfs一遍,途中经历的所有点的最早祖先都标记为这个点。然后,扫一遍所有点,如果这个点的祖先所在的那一组还没被连接,ans++
记得减去s(如果s本身就是祖先的话);
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int N=5005;
vector<int>G[N];
bool vis[N];
int par[N];
void dfs(int fa,int x)
{
if(par[x]==fa)return;
par[x]=fa;
for(auto a:G[x])
dfs(fa,a);
}
int main()
{
int n,m,s,i,j,k;
cin>>n>>m>>s;
for(i=1;i<=m;i++){
int a,b;scanf("%d%d",&a,&b);
G[a].push_back(b);
}
dfs(s,s);
for(i=1;i<=n;i++){
if(!par[i])
dfs(i,i);
}
int ans=0;
for(i=1;i<=n;i++){
if(!vis[par[i]]){
ans++;vis[par[i]]=true;
}
}
cout<<ans-(vis[s]?1:0)<<endl;
return 0;
}