题目:A. Three Pairwise Maximums
题意:
找到这样的a,b,c。
显然x,y,z都是a,b,c里头的数,直接枚举a,b,c也可以。
无论a,b,c是什么大小关系,x,y,z一定要有2,3个相同的,否则NO。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=1e9+7;
const int MAXlen=1e5+10;
double eps=1e-4;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,i,j,x,y,z;
scanf("%d %d %d",&x,&y,&z);
if(x!=y&&x!=z&&y!=z)
{
printf("NO\n");
continue;
}
else if(x==y&&y==z)
{
printf("YES\n");
printf("%d %d %d\n",x,x,x);
}
else
{
if(x==y&&x>=z)
{
printf("YES\n");
printf("%d %d %d\n",x,z,z);
}
else if(x==z&&x>=y)
{
printf("YES\n");
printf("%d %d %d\n",y,x,y);
}
else if(y==z&&z>=x)
{
printf("YES\n");
printf("%d %d %d\n",x,x,z);
}
else
printf("NO\n");
}
}
return 0;
}
题目:B. Restore the Permutation by Merger
题意:问两个相同的数组(1–n)相互插入(但是同一个数组的顺序不能乱),找到这个数组的原来顺序。
直接找不同的数。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=1e9+7;
const int MAXlen=1e5+10;
double eps=1e-4;
int a[200];
int book[200];
int ans[55];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(book,0,sizeof(book));
int n,i,j,len=0;
scanf("%d",&n);
n*=2;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
{
if(!book[a[i]])
{
ans[++len]=a[i];
book[a[i]]=1;
}
}
for(i=1;i<=len;i++)
printf("%d ",ans[i]);
printf("\n");
}
return 0;
}
题目:C. Make It Good
题意:问最小删除前缀的个数,使得a数组能变为不递减c数组,每次从头或者尾放入c。
最小,所以要找后缀最大,不递减说明我们需要后缀是一个单调的序列,或者是类似开口向下的抛物线的大小规律。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=1e9+7;
const int MAXlen=1e5+10;
double eps=1e-4;
int a[200100];
int dp[200100];
int n;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int i,j;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
if(n==1)
{
printf("0\n");
continue;
}
int sum=1;
bool flag=true;;
for(i=n-1;i>=1;i--)
{
if(flag)
{
if(a[i]>=a[i+1])
{
sum++;
}
else
{
sum++;
flag=false;
}
continue;
}
else
{
if(a[i]<=a[i+1])
{
sum++;
continue;
}
else
break;
}
}
int ans=1;
for(i=n-1;i>=1;i--)
{
if(a[i]<=a[i+1])
ans++;
else
break;
}
printf("%d\n",n-max(ans,sum));
}
return 0;
}
题目:D. a-Good String
题意:问最小的变换次数让字符串为’a’-good串。
由于判断’a’-good有三种情况,依次入手。
长度大于1时,要求整个串是’a’-good,那么前n/2或者后n/2一定要是‘a’,
所以我们分治求。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=1e9+7;
const int MAXlen=1e5+10;
double eps=1e-4;
//17
char s[131172];
int solve(int l,int r,char temp)
{
if(l==r)
{
return (s[l]!=temp);
}
int mid=(l+r)/2;
int suml=0,sumr=0;
for(int i=l;i<=mid;i++)
{
suml+=(s[i]!=temp);
}
for(int i=mid+1;i<=r;i++)
{
sumr+=(s[i]!=temp);
}
return min(suml+solve(mid+1,r,temp+1),sumr+solve(l,mid,temp+1));
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int i,j,n;
scanf("%d",&n);
scanf("%s",s+1);
if(n==1)
{
if(s[1]=='a')
printf("0\n");
else
printf("1\n");
continue;
}
printf("%d\n",solve(1,n,'a'));
}
return 0;
}
题目:E. Directing Edges
题意:给了n个点,m条边,给的边有的是有向边有的是无向边。
问能否把无向边变有向边之后整个图没有环。没有的话,给出m条边的连接情况。
首先判段环,用拓扑排序。如果有环则NO,否则一定存在,可以画个草图,当无向边未有环没关系,有环的时候另一条边反向。之后利用拓扑排序的顺序进行建边。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=1e9+7;
const int MAXlen=2e5+10;
double eps=1e-4;
int n,m;
vector<int>hh[MAXlen];
int INdeg[MAXlen],u[MAXlen],v[MAXlen],num,cnt[MAXlen];
queue<int>q;
void topsort()
{
num=0;
while(!q.empty())
q.pop();
for(int i=1;i<=n;i++)
{
if(!INdeg[i])
q.push(i);
}
while(!q.empty())
{
int temp=q.front();
q.pop();
cnt[temp]=(++num);
for(int i=0;i<hh[temp].size();i++)
{
int uu=hh[temp][i];
INdeg[uu]--;
if(INdeg[uu]==0)
{
q.push(uu);
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int i,j;
scanf("%d %d",&n,&m);
num=0;
for(i=0;i<=n;i++)
{
cnt[i]=INdeg[i]=0;
hh[i].clear();
}
for(i=1;i<=m;i++)
{
int op;
scanf("%d %d %d",&op,&u[i],&v[i]);
if(op)
{
INdeg[v[i]]++;
hh[u[i]].push_back(v[i]);
}
}
topsort();
if(n>num)
{
printf("NO\n");
continue;
}
printf("YES\n");
for(i=1;i<=m;i++)
{
if(cnt[u[i]]<cnt[v[i]])
printf("%d %d\n",u[i],v[i]);
else
printf("%d %d\n",v[i],u[i]);
}
}
return 0;
}
题目:F.Removing Leaves
题意:给定一棵n节点的树,每次你可以选择k个叶子节点删除,问最多能删几次。
有点带拓扑排序的意思,我们先找到所有的叶子节点,进行删除,用cnt[]数组记录该点子节点的删除个数,达到k个,答案++,判断度为1否,是的话加入拓扑序中。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=1e9+7;
const int MAXlen=2e5+10;
double eps=1e-4;
int n,m;
vector<int>hh[MAXlen];
int INdeg[MAXlen],num,cnt[MAXlen];
queue<int>q;
int book[MAXlen];
int k;
void topsort()
{
while(!q.empty())
q.pop();
for(int i=1;i<=n;i++)
{
if(INdeg[i]==1)
{
q.push(i);
}
}
while(!q.empty())
{
int temp=q.front();
q.pop();
book[temp]=1;
for(int i=0;i<hh[temp].size();i++)
{
int uu=hh[temp][i];
if(book[uu])
continue;
INdeg[uu]--;
INdeg[temp]--;
cnt[uu]++;
if(cnt[uu]==k)
{
num++;
cnt[uu]=0;
if(INdeg[uu]==1)
q.push(uu);
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int i,j;
scanf("%d %d",&n,&k);
for(i=0;i<=n;i++)
{
hh[i].clear();
book[i]=cnt[i]=INdeg[i]=0;
}
num=0;
for(i=1;i<n;i++)
{
int x1,x2;
scanf("%d %d",&x1,&x2);
hh[x1].push_back(x2);
hh[x2].push_back(x1);
INdeg[x1]++;
INdeg[x2]++;
}
topsort();
printf("%d\n",num);
}
return 0;
}