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??
显然不是。
我们考虑两个字符串。
不显然的是,如果我们发现所有字符的数量都是偶数就一定有一种合法方案。
从头向后扫,如果发现两位不相等我们应该如何换。
- 可以从第一个字符串的后面(前面都相等了)拿一个一样的换给第二个。
- 可以从第二个字符串的后面拿一个一样的换给第二个。
上述的构造保证交换次数小于$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
Miemeng真的蒻