D:
给两种操作,问最少需要多少次操作可以使得数组所有数字相等。
找出出现次数最多的数字x,以他为基准向左向右扫一遍数组,找x!=y,如果y<x,则给y执行操作一,否则操作二。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
map<int,int>m;
const int maxn=2e5+7;
struct Node{
int id;
int w;
int ci;
bool operator <(const Node& x)const{
return ci>x.ci;
}
}b[maxn];
int a[maxn];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
b[a[i]].id=i;
b[a[i]].w=a[i];
++b[a[i]].ci;
}
sort(b,b+maxn);
int x=n-b[0].ci;
printf("%d\n",x);
if(!x) return 0;
int id=b[0].id;
int w=b[0].w;
for(int i=id-1;i>=1;--i){
if(a[i]>w)
printf("%d %d %d\n",2,i,id);
else if(a[i]<w)
printf("%d %d %d\n",1,i,id);
id=i;
}
id=b[0].id;
for(int i=id+1;i<=n;++i){
if(a[i]>w)
printf("%d %d %d\n",2,i,id);
else if(a[i]<w)
printf("%d %d %d\n",1,i,id);
id=i;
}
return 0;
}
E:
给两个长度为k的字符串s,t,并且字典序s<t,而且字典序在s与t之间的字符串有奇数个,在奇数个字符串组成的序列中寻找中间串,并输出。
首先我们考虑两个十进制数字的中间值怎么找,a和b,中间值为:(a+b)/2,那么字符串也是同理,是二十六进制下的寻找中间值,模拟二十六进制加法,再计算其除以2的值,即为结果串。
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<string>
#include<queue>
using namespace std;
const int maxn=2e5+7;
char s[maxn],t[maxn];
string h;
int a[maxn];//每一位的二十六进制数;
int main(){
int k;
cin>>k>>s>>t;
h="";
int res=0;
int jin=0;//进位;
int j=0;
for(int i=k-1;i>=0;--i){
int yu=(s[i]-'a'+t[i]-'a'+jin)%26;
a[j++]=yu;
jin=(s[i]-'a'+t[i]-'a'+jin)/26;
}
int x=0;
if(jin) a[j++]=jin;
for(int i=j-1;i>=0;--i){
x=x*26+a[i];
//比如两个串长度为k 由于产生进位出现长度为k+1,那么最高位我们是不要的。
if(i>=k){
x%=2;
continue;
}
h+='a'+(x/2);
x%=2;
}
cout<<h<<endl;
return 0;
}
E:给出一个无自环,无重边,无向连通图,问能否将该无向图转换为有向图,使得每条路径长度都为1。
图着色,将每个点着色,如果可行,说明可以转化为有向图,白->黑为正向边,黑->白为反向边,输出的时候,由于使用邻接表存图,那么正向边下标为偶数,反向边为奇数,且正向边^1=反向边的下标。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
const int maxn=2e5+7;
int head[maxn];
int top;
void init(){
top=0;
memset(head,-1,sizeof(head));
}
struct Edge{
int v,next;
}edge[maxn<<1];
void add(int u,int v){
edge[top].v=v;
edge[top].next=head[u];
head[u]=top++;
}
int color[maxn];
bool dfs(int u,int f){
color[u]=f;
bool flag=true;
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(color[v]==color[u]) return 0;
if(color[v]==-1){
flag=flag&dfs(v,f^1);
}
}
return flag;
}
int a[maxn];
int main(){
int n,m;
scanf("%d%d",&n,&m);
init();
int u,v;
for(int i=0;i<m;++i){
scanf("%d%d",&u,&v);
//++mm[make_pair(u,v)];
add(u,v);
add(v,u);
}
memset(color,-1,sizeof(color));
if(dfs(1,0)){
printf("YES\n");
for(int i=0;i<m;++i){
int id=i*2;
if(color[edge[id].v]==0) printf("1");
else printf("0");
}
printf("\n");
}
else
printf("NO\n");
return 0;
}