The 2016 Asia Regional Contest, Tsukuba
一个1到n的有序数组,每次将一个数提前,输出最终序列。
struct node
{
int x,id;
}a[N];
int cmp(node a,node b)
{
return a.x<b.x;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
int tot=2*n;
for(int i=n;i>=1;i--) a[i].x=--tot,a[i].id=i;
while(m--)
{
int x;
scanf("%d",&x);
a[x].x=--tot;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++) printf("%d%c",a[i].id,i==n?'\n':' ');
}
return 0;
}
0到9999的数,不足四位高位自动补0,用表生成一个校验码,加在最后面,然后如果这个五位数所有的变形有一种和它生成的校验码冲突了,ans++。
int vis[20][20];
int get_num(int a[],int f)
{
int he=0;
for(int i=0;i<f;i++)
he=vis[he][a[i]];
return he;
}
int judge(int aa)
{
//printf("aa=%d\n",aa);
int a[10];
for(int i=0;i<10;i++)
a[i]=0;
int cont=3;
while(aa)
{
a[cont--]=aa%10;
aa/=10;
}
int num=get_num(a,4);
a[4]=num;
int he=get_num(a,5);//printf("num=%d he=%d\n",num,he);
if(he!=0) return 1;
for(int i=0;i<5;i++)
{
int tmp=a[i];
for(int j=0;j<=9;j++)
{//printf("i=%d j=%d\n",i,j);
a[i]=j;
if(j==tmp) continue;
if(get_num(a,5)==he)
{
// for(int i=0;i<5;i++)
// printf("%d",a[i]);
// printf("\naa=%d\n",aa);
return 1;
}
}
a[i]=tmp;
}//printf("asdasd\n");
for(int i=0;i<4;i++)
{
if(a[i]==a[i+1]) continue;
swap(a[i],a[i+1]);
if(get_num(a,5)==he)
{
// for(int i=0;i<5;i++)
// printf("%d",a[i]);
// printf("\naa=%d\n",aa);
return 1;
}
swap(a[i],a[i+1]);
}
return 0;
}
int main()
{
for(int i=0; i<10; i++)
for(int j=0; j<10; j++)
scanf("%d",&vis[i][j]);
int sum=0;
for(int i=0; i<=9999; i++)
{
if(judge(i))
{//printf("iiiiiiiiiiiiiiiiiiii=%d\n",i);
sum++;
}
}
printf("%d\n",sum);
return 0;
}
C - Distribution Center
求每条线最多有多少条线上的货物会经过。贪心排序,先把x小的更新,从左往右从右往左各自扫一遍。
int vis[N][2];
struct node
{
int x,y;
} a[N];
int cmp1(node a,node b)
{
if(a.x!=b.x) return a.x<b.x;
return a.y<b.y;
}
int cmp2(node a,node b)
{
if(a.x!=b.x) return a.x<b.x;
return a.y>b.y;
}
int ans[N];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
cls(vis,0);
cls(ans,0);
int mm=m+1,num=0;
for(int i=1; i<=m; i++)
scanf("%d%d",&a[i].x,&a[i].y);
sort(a+1,a+m+1,cmp1);
for(int i=1; i<=m; i++)
vis[a[i].y+1][1]=max(vis[a[i].y][1]+1,vis[a[i].y+1][1]);
sort(a+1,a+m+1,cmp2);
for(int i=1; i<=m; i++)
vis[a[i].y][2]=max(vis[a[i].y+1][2]+1,vis[a[i].y][2]);
for(int i=1; i<=n; i++)
{
// printf("y=%d 1==%d 2==%d\n",a[i].y,vis[a[i].y][1],vis[a[i].y][2]);
ans[i]=vis[i][1]+vis[i][2]+1;
}
for(int i=1;i<=n;i++) printf("%d%c",ans[i],i==n?'\n':' ');
}
return 0;
}
D - Hidden Anagrams
貌似之前做过,暴力将所有的字串预处理,扔进unorder_set里面,用unorder_map会MLE。
ul base=131;
char s1[N],s2[N];
ul p[N],ha[N],vis[27];
unordered_set<ul>S;
int main()
{
p[0]=1;
for(int i=1; i<N; i++) p[i]=p[i-1]*base;
while(~scanf("%s%s",s1+1,s2+1))
{
int len1=strlen(s1+1);
int len2=strlen(s2+1);
ha[0]=0;
S.clear();
for(int i=1; i<=len1; i++)
{
for(int j=0; j<=26; j++) vis[j]=0;
for(int j=i; j<=len1; j++)
{
vis[s1[j]-'a']++;
ul tmp=0;
for(int k=0; k<26; k++)
tmp=tmp*base+vis[k];
S.insert(tmp);
}
}
int ans=0;
for(int i=1; i<=len2; i++)
{
for(int j=0; j<=26; j++) vis[j]=0;
for(int j=i; j<=len2; j++)
{
vis[s2[j]-'a']++;
ul tmp=0;
for(int k=0; k<26; k++)
tmp=tmp*base+vis[k];
if(S.find(tmp)!=S.end()) ans=max(ans,j-i+1);
}
}
pd(ans);
}
return 0;
}
const int N=4000+10;
char s1[N],s2[N];
int vis[500];
int vis1[N][28],vis2[N][28];
int len1,len2;
//map<ul,int>q;
set<ul>s;
bool judge(int mid)
{
for(int i=mid; i<=len2; i++)
{
ul sum=0;
for(int k=0; k<26; k++)
sum+=(sum<<4)+(vis2[i][k]-vis2[i-mid][k]);
if(s.count(sum)) return true;
}
return false;
}
int main()
{
while(~scanf("%s%s",s1+1,s2+1))
{
len1=strlen(s1+1),len2=strlen(s2+1);
// q.clear();
s.clear();
memset(vis1,0,sizeof(vis1));
memset(vis2,0,sizeof(vis2));
for(int i=1; i<=len1; i++)
{
for(int j=0; j<26; j++) vis1[i][j]=vis1[i-1][j];
vis1[i][s1[i]-'a']++;
}
for(int i=1; i<=len2; i++)
{
for(int j=0; j<26; j++) vis2[i][j]=vis2[i-1][j];
vis2[i][s2[i]-'a']++;
}
for(int i=1; i<=len1; i++)
for(int j=i; j<=len1; j++)
{
ul sum=0;
for(int k=0; k<26; k++)
sum+=(sum<<4)+(vis1[j][k]-vis1[i-1][k]);
s.insert(sum);
// if(!q[sum]) q[sum]=j-i+1;
// else q[sum]=max(q[sum],j-i+1);
}
int ans=min(len1,len2);
while(ans)
{
if(judge(ans)) break;
ans--;
}