洛谷P4305 [JLOI2011]不重复数字
作者:互联网
题目链接:https://www.luogu.com.cn/problem/P4305
题目描述 给定 n 个数,要求把其中重复的去掉,只保留第一次出现的数。 输入格式 本题有多组数据。 第一行一个整数 T ,表示数据组数。 对于每组数据: 第一行一个整数 n 。 第二行 n 个数,表示给定的数。 输出格式 对于每组数据,输出一行,为去重后剩下的数,两个数之间用一个空格隔开。 输入输出样例 输入 #1 2 11 1 2 18 3 3 19 2 3 6 5 4 6 1 2 3 4 5 6 输出 #1 1 2 18 3 19 6 5 4 1 2 3 4 5 6
对于这道题,可以先让s[i]表示第i个数个值,定义结构体a[i].s=s[i],a[i].h=i,处理完之后a[i].s=s[a[i].h],之后对a[i].s进行归并排序,
排序之后循环如果a[i].h=a[i-1].h就说明a[i]是重复的,即s[a[i].h]不输出,就将a[i].h打上标记(flag[a[i].h]),
最后将没有标记的s[i]输出。
代码:
#include<stdio.h> int t,n,s[50001],flag[50001]; struct node{ int s,h; }a[50001],r[50001]; int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } void px(int s,int t){ if(s==t)return; int mid=(s+t)>>1; px(s,mid);px(mid+1,t); int i=s,j=mid+1,k=s; while(i<=mid&&j<=t) if(a[i].s<=a[j].s)r[k++]=a[i++]; else r[k++]=a[j++]; while(i<=mid)r[k++]=a[i++]; while(j<=t)r[k++]=a[j++]; for(i=s;i<=t;i++)a[i]=r[i]; return; } int main(){ t=read(); while(t--){ n=read(); for(int i=1;i<=n;i++)s[i]=read(); for(int i=1;i<=n;i++)a[i]=(struct node){s[i],i}; for(int i=1;i<=n;i++)flag[i]=0; px(1,n); for(int i=2;i<=n;i++)if(a[i].s==a[i-1].s)flag[a[i].h]=1; printf("%d",s[1]); for(int i=2;i<=n;i++)if(flag[i]==0)printf(" %d",s[i]); printf("\n"); } return 0; }
我可能写的不好,如果有问题,请帮忙指出,谢谢。
标签:50001,ch,洛谷,JLOI2011,输出,int,mid,while,P4305 来源: https://www.cnblogs.com/sy666/p/12775564.html