zoukankan      html  css  js  c++  java
  • CodeForces

    /*
      此题略坑的是,最终输出的那个数列,不能有重复的数字,这个坑点之前一直没发现,结果一直WA,其实题目也没明说这一点,但是对某组数据的解释中,有一句“只有一种答案”,可以从这句中猜测出来
      
      借鉴自代码:
      http://blog.csdn.net/senyelicone/article/details/72909698
      不过我略作了修改,省去了一次循环...即博客代码中的
      
      for(int i=1;i<=n;i++) if(a[i]==b[i]) c[i]=a[i],k[c[i]]=1;  
            else now=i;
    以及
    for(int i=1;i<=n;i++)  
              if(a[i]==b[i]) c[i]=a[i],k[c[i]]=1;  
              else d[tot--]=i;  
    
    ---0824更新---
    后来发现我错怪cf了,是我自己英语不好,导致专有术语认不出来的锅
    combination和permutation分别是组合和排列的英文单词,按照数学中的排列组合的定义,一组排列中的所有数字,本就是不能有重复的...
    看来除了好好练编程,还得好好学英语
      
    */



    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1005;
    int a[N], b[N], c[N], v[N];
    int d[5];
    //a、b为输入的两个数列,c为最终的输出数列,v用来记录,c数组的各位置的值是否已经确定(因为c中所有数字,最多只能用一次,注意permutation是排列,以及排列的定义)
    //d[i]中的值,用来记录不相等的第i对数字的下标 
    int main()
    {
    //	cin.tie(0);
    //  cin.sync_with_stdio(false);
      	
    	int n;
    	while (cin >> n)
    	{
    		memset(v, 0, sizeof(v));
    		int tot = 0, kase = 1, temp;
    		for (int i = 1; i <= n; i++) cin >> a[i];
    		for (int i = 1; i <= n; i++) cin >> b[i];
    		
    		for (int i = 1; i <= n; i++)
    		{
    			if (a[i] == b[i])
    			c[i] = a[i], v[a[i]] = 1; //相等的直接作为c[i]的值,v数组 v[i] = 1的意义是,数字i在c数组中已经出现过了
    			else
    			tot++, d[kase++] = i;//tot记录失配隔宿,d数组 d[i] = b表示第i次失配是在a[b]的位置
    		}
    		if (tot == 1)
    		{
    			for (int i = 1; i <= n; i++)
    			if (!v[i]) temp = i;
    			c[d[1]] = temp;
    		}
    		else
    		{
    			if ( a[d[1]] == b[d[2]] || v[a[d[1]]] || v[b[d[2]]] ) //2个失配位置的情况,如果对某个失配位置,如果数组a在该位置的值,已经在c数组中出现过了,则数组c的该位置。应填入数组b在该失配位置的值
    			//如果失配位置标号1和2,且a1 == b2,则c数组中的对应位置应选取a2和b1,这样才能保证两个数列都恰好1个位置和c数列不同
    			c[d[1]] = b[d[1]], c[d[2]] = a[d[2]];
    			else
    			c[d[1]] = a[d[1]], c[d[2]] = b[d[2]];
    		}
    		cout << c[1];
    		for(int i = 2; i <= n; i++)
    		cout << " " << c[i];
    		cout << endl;
    		
    	} 
    	return 0;
    }


    /*cf上的代码
    
    
    它的思路更为特别,因为题目要求输出的数组不能有重复元素,也即1~n出现且仅出现一次,但是,数组a中又有(n-1)个元素和输出的数组的元素一样,所以,1~n中一定有一个数据没出现,数组a中的(n-1)种元素,一定有一个元素出现了两次,把出现了两次的元素找出来,先把该元素第一次出现的位置,赋值为没出现过的那个元素,若a换完后,和b刚好一个元素不同,则更换成功,否则将x赋值回第一次出现的位置,对第二次出现的位置,再赋值...该代码中,两个位置是用循环找的,但我觉得,可以在找x时,就把x出现的2个位置记录下来...用一个pair,辅助变量kase记录下2次分别是在什么位置出现,少掉一次循环
    
    此外,找x和找y比较特殊,因为找x时,还要找到x对应的两个下标,所以,i从1到n的循环,枚举的是fre[a[i]];而找y时,如果继续这样枚举,是找不到的,因为,既然fre[a[i]]都等于0了,说明,我想要找的那个频次为0的数,在数组a中根本没出现,如果还那样找,就根本找不到...所以找y时,是换成了i从1到n循环,枚举fre[i]本身,这点尤其注意!!!因为一开始,我也没有想得很透彻清楚,我最初写的时候,就出现了找y找不到的局面
    
    以及,后来WA了一次,仔细检查发现,fre每次循环都有memset清零,我忘记写了...这个错误经常犯,尤其多组数据时,很多次WA都是因为没有清空上组的数据,慎之!
    
    参考了cf上的一段代码,因为不是blog贴不了网址,不过源代码就是下面这样:
    (下次来填一个坑,怎么在cf上查看后台数据以及别人的正确代码)
    
    #include <bits/stdc++.h>
    using namespace std;
    int a[1002],b[1002],fr[1002];
    int main()
    {
    		int n,x,y;
    		cin>>n;
    		for(int i=0;i<n;i++)
    		{
    			cin>>a[i];
    			fr[a[i]]++;
    		}
    		for(int i=0;i<n;i++)
    			cin>>b[i];
    		for(int i=1;i<=n;i++)
    		{
    			if(fr[i]==2)
    				x=i;
    			if(fr[i]==0)
    				y=i;
    		}
    		for(int i=0;i<n;i++)
    		{
    			if(a[i]==x)
    			{
    				a[i]=y;
    				int ct=0;
    				for(int j=0;j<n;j++)
    					if(a[j]!=b[j])
    						ct++;
    				if(ct==1)
    				{
    					for(int k=0;k<n;k++)
    						cout<<a[k]<<" ";
    					return 0;
    				}
    				a[i]=x;
    			}
    		}
    	return 0;
    }
    */


    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1005;
    int a[N], b[N],fre[N]; // fre is short for frequency
    pair<int, int> same; //记录a中出现过2次的数,分别是在哪两个位置出现
    void printa(int n)
    {
    	cout << a[1];
    	for (int i = 2; i <= n; i++)
    	cout << " " << a[i];
    	cout << endl; 
    }
    int main()
    {
    	int n;
    	while (cin >> n)
    	{
    		memset(fre, 0, sizeof(fre));
    		int kase = 0, x, y; //x是出现两次的数,y是没出现的数,kase是标记当前找的是x的第几次出现
    		for (int i = 1; i <= n; i++) cin >> a[i], fre[a[i]]++;
    		for (int i = 1; i <= n; i++) cin >> b[i];
    		
    		for (int i = 1; i <= n; i++)
    		{
    			if (fre[a[i]] == 2) //出现两次的数,究竟是在a的哪个下标出现了两次,分别记录下来 
    			{
    				 x = a[i];
    				 if (!kase) kase++, same.first = i;
    				 else kase++, same.second = i;
    			}
    			if (fre[i] == 0) y = i;
    		}
    	//	cout << "x = " << x << " y = " << y << " first = " << same.first << " second = " << same.second << endl;
    		
    		a[same.first] = y; int cnt = 0;
    		for (int i = 1; i <= n; i++)
    		{
    			if (a[i] != b[i]) cnt++;
    		}
    		if (cnt == 1)
    		{
    			printa(n);
    			continue;
    		}
    	//	cout << "test: " << x << " " << y << endl;
    		
    		a[same.first] = x, a[same.second] = y;
    		printa(n);
    	}
    	return 0;
    }


  • 相关阅读:
    CentOS 安装Redis
    python中Url链接编码处理(urlencode,urldecode)
    Flask+mongodb 实现简易个人博客
    Flask中mongodb实现flask_login保持登录
    ubuntu环境变量添加变量
    终端执行python shell的方法
    简单的模拟登录Wap版新浪微博
    爬取淘宝模特信息并自动保存图片
    Python字符串的encode与decode
    python3 安装scrapy Exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 1006, in check_if_exists解决方法
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789510.html
Copyright © 2011-2022 走看看