A
使用优先队列再进行拓扑排序即可,注意多组输入,每次初始化vis,g,in数组
#include<bits/stdc++.h>
//#pragma GCC optimize(2)
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
#define pb push_back
using namespace std;
int n,m,in[510],vis[510];//入度,标记
std::vector<int> g[510];//存图
priority_queue<int,vector<int>,greater<int> >q;
int main(){
while(cin>>n>>m){
memset(in,0,sizeof in);
rep(i,1,n) g[i].clear();
memset(vis,0,sizeof vis);
rep(i,1,m){
int a,b;
cin>>a>>b;
g[a].pb(b);
in[b]++;
}
rep(i,1,n){
if(in[i]==0){
q.push(i);
}
}
int f=1;//控制格式
while(q.size()){
int now=q.top();q.pop();
if(vis[now]==0){
if(f)
cout<<now,f=0;
else cout<<" "<<now;
vis[now]=1;
}
for(auto it:g[now]){
in[it]--;
if(!vis[it]&&in[it]==0){
q.push(it);
}
}
}
cout<<endl;
}
return 0;
}
B
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define TT int T;cin>>T;while(T--)
int main(){
TT{
ll a,b;
cin>>a>>b;
if(a%b==0) cout<<0<<endl;
else {
cout<<b-a%b<<endl;
}
}
return 0;
}
C
研究倒数第2个b所处不同位置对应的形态
aaabb 1 1种形态
aabab 1
aabba 2 2种形态
abaab 1
ababa 2
abbaa 3 3种形态
baaab 1
baaba 2
babaa 3
bbaaa 4 4种形态
可以看到 第2个b所处不同位置对应的形态
确定了了 第2个b所处位置后,第1个b所处位置,也就容易确定了。
递增规律也就找到了。
#include <stdio.h>
#define maxn 100010
#define LL long long
LL cnt[maxn],sum[maxn];//cnt[i]记录倒数第2个b,所处字串倒数第i位时,对应的形态数量
char s[maxn];
int main(){
int i,t,n,k,j;
for(i=2;i<=100000;i++)cnt[i]=cnt[i-1]+1,sum[i]=sum[i-1]+cnt[i];//sum[i]记录cnt[i]的前缀和
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&k);
for(i=2;i<=n;i++)
if(k<=sum[i])break;
j=i,k-=sum[j-1];
for(i=1;i<=n;i++)s[i]='a';//字串先用a填充
s[n+1]='\0';//字串结尾标记。
s[n-j+1]='b';//记录倒数第2个b所处字串位置
s[n-k+1]='b';//记录倒数第1个b所处字串位置
printf("%s\n",s+1);
}
return 0;
}
D
就是说max(a,b)就是a和b中的最大值得最小化,贪心,从第一位开始,最小化的话,2=1+1,0=0+0,1=1+0,当1的时候就要分辨大小了,我设第一个字符串为最大的,所以先要让第一个为1,第二个为2,然后退出去,因为要保证最大值得最小化,现在第一个字符串就是最大的,所以要保证之后的都是最小的数字,所以之后第一个都是0,第二个字符是本来的那个元素,然后就可以求出最大值的最小化的数字了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
int main ()
{
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
getchar();
string ch;//本身的那个数字
cin>>ch;
string a,b;//拆成的两个数字
int i;
for(i=0;i<n;i++){
if(ch[i]=='2'){
a=a+'1';b=b+'1';//2的话平分成1+1
}
else if(ch[i]=='1'){//1的话,让第一是最大的数字为1,第二个为0
a=a+'1';b=b+'0';break;
}
else if(ch[i]=='0'){
a=a+'0';b=b+'0';//0的话平分成0+0
}
}
for(int j=i+1;j<n;j++){
a=a+'0';b=b+ch[j];//是第一个最大的保持最小化为0,第二个为原本数字
}
cout<<a<<endl;
cout<<b<<endl;
}
return 0;
}
F
直接可以看出 x 等于剩余剑数最多的那种剑,每个人拿的剑相同,所以
应该是差值的最大公约数
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+500;
long long gcd(long long a, long long b){
return b == 0 ? a : gcd(b, a%b);
}
ll a[maxn];
int main(){
int n;
cin >> n;
ll sum = 0, ma = 0;
for(int i = 1; i <= n; i++){
cin >> a[i];
ma = max(ma, a[i]);
}
ll ans = ma - a[1];
sum = ma - a[1];
for(int i = 2; i <= n; i++){
sum = sum + (ma - a[i]);
ans = gcd(ma-a[i], ans);
}
cout << sum / ans << " " << ans << endl;
return 0;
}
F
先取最大的,然后依次取最小的
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define TT int T;cin>>T;while(T--)
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define PII pair<int,int>
#define fi first
#define se second
#define debug(a) cout <<#a << "=" << a << endl;
#define per(i,a,n) for (int i=a;i>=n;i--)
int main(){
int n;
PII a[1010];
vector<int> v;
cin>>n;
rep(i,1,n) {
cin>>a[i].fi;
a[i].se=i;
}
sort(a+1,a+1+n);
ll ans=1,k=1;
per(i,n-1,1){
ans+=k*a[i].fi+1;
k++;
v.push_back(a[i].se);
}
cout<<ans<<endl;
cout<<a[n].se<<" ";
for(auto it:v)
cout<<it<<" ";
return 0;
}