• Codeforces Round #599 (Div. 2)的简单题题解


    难题不会啊……

    我感觉写这个的原因就是因为……无聊要给大家翻译题面

    A. Maximum Square

    简单题意:

    有$n$条长为$a_i$,宽为1的木板,现在你可以随便抽几个拼在一起,然后你要从这一大块木板中裁出一块最大的正方形。

    $1 leq a_i leq n leq 1000$

    多测,$T leq 10$

    给个官网的图:

    直接排序然后扫就行了,这数据范围是不是让你想什么神奇东西了?

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #define N 1111
     
    using namespace std;
     
    int wn,arr[N];
    int ans=0;
    int main(){
    	int T;
    	cin.sync_with_stdio(false);
    	cin>>T;
    	while(T--){
    		ans=0;
    		cin>>wn;
    		for(int i=1;i<=wn;i++)
    			cin>>arr[i];
    		sort(arr+1,arr+wn+1);
    		for(int i=1;i<=wn;i++){
    			ans=max(ans,min(arr[i],wn-i+1));
    		}
    		cout<<ans<<endl;
    	}
    }
    

    B1.Character Swap (Easy Version)

    字符交换……是不是想到点什么,然鹅并不是原题XD。

    这是简单版,但是两个题面一样,翻译一下:

    简单题意:

    小U有两个长度相等且为$l$的字符串,现在他想通过交换来使这两个字符串相等。

    我们定义交换$<i,j>$为:将第一个字符串的$i$位的字符与第二个字符串的第$j$位交换。

    简单版只要求你输出能否成立。$l leq 10^4$


    而且简单版的交换次数保证为$1$

    于是……

    $Theta(N)$暴扫。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #define L 11111
     
    using namespace std;
     
    char sta[L],stb[L];
    int len;
    int main(){
    	int T;
    	cin.sync_with_stdio(false);
    	cin>>T;
    	while(T--){
    		int fi=-1,se=-1;
    		cin>>len>>sta>>stb;
    		for(int i=0 ;i<len;i++){
    			if(sta[i]!=stb[i]){
    				if(fi==-1)     fi=i;
    				else if(se==-1)se=i;
    				else {
    					puts("No");
    					goto nxt;
    				}
    			}
    		}
    //		cout<<fi<<" "<<se<<endl;
    		if(fi!=-1 && se!=-1 && stb[fi]==stb[se] && sta[se]==sta[fi])
    			puts("Yes");
    		else puts("No");
    nxt:;
    	}
    }
     

    B2.Character Swap (Hard Version)

    坤男困难版要输出方案。

    而且交换次数要小于$2l$。

    ……思考ing

    觉得非常可做。

    但是$l leq 50$(?)

    难道是……Meet in the Middle??

    显然不是。

    我们考虑两个字符串。

    不显然的是,如果我们发现所有字符的数量都是偶数就一定有一种合法方案。

    从头向后扫,如果发现两位不相等我们应该如何换。

    1. 可以从第一个字符串的后面(前面都相等了)拿一个一样的换给第二个。
    2. 可以从第二个字符串的后面拿一个一样的换给第二个。

    上述的构造保证交换次数小于$2l$。

    证明?

    对于每个点,只能进行1操作或2操作。而1操作有1次交换,2操作有2次交换(一换给二,二换给一)。

    那么最劣情况下交换次数不会多于$2l$

    所以……

    $Theta(N^2)$

    这是一道贪心题,惊不惊喜,意不意外?

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #define N 55
     
    using namespace std;
     
    char str1[N],str2[N];
    int val[27],len;
    vector <pair<int,int> >anss;
    int main(){
    	int T;
    	cin.sync_with_stdio(false);
    	cin>>T;
    	while(T--){
    		cin>>len>>str1+1>>str2+1;
    		anss.clear();
    		memset(val,0,sizeof val);
    		for(int i=1;i<=len;i++){
    //			cout<<str1[i]-'a'<<endl;
    			val[str1[i]-'a']++;
    			val[str2[i]-'a']++;
    		}
    		for(int i=0;i<26;i++){
    //			cout<<i<<" "<<val[i+'a']<<endl;
    			if(val[i]%2==1){
    				cout<<"No"<<endl;
    				goto nxt;
    			}
    		}
    		cout<<"Yes"<<endl;
    		for(int i=1;i<=len;i++){
    			if(str1[i]!=str2[i]){
    				for(int j=i+1;j<=len;j++){
    					if(str1[i]==str1[j]){
    						anss.push_back(make_pair(j,i));
    						swap(str1[j],str2[i]);
    						break;
    					}
    					if(str1[i]==str2[j]){
    						anss.push_back(make_pair(j,j));
    						anss.push_back(make_pair(j,i));
    						swap(str1[j],str2[j]);
    						swap(str1[j],str2[i]);
    						break;
    					}
    				}
    			}
    		}
    		cout<<anss.size()<<endl;
    		for(auto i:anss)
    			cout<<i.first<<" "<<i.second<<endl;
    		nxt:;
    	}
    }
    

    你不觉得剩下的题有点难么?

    其实是还没做QAQ

  • 相关阅读:
    HNOI2003 消防局的设立
    APIO2007 风铃
    SDOI2006 保安站岗
    消息传递
    [POI2008]STA-Station
    JLOI2015 城池攻占
    BOI2004 sequence
    Monkey King
    APIO2012 Dispatching
    HTML meta 文本 格式排版 链接图表 列表 表单 frame后台布局实例
  • 原文地址:https://www.cnblogs.com/kalginamiemeng/p/11862750.html
Copyright © 2020-2023  润新知