A:http://codeforces.com/contest/1360/problem/A
题意:
用最小正方形,容下两个相同矩形。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; int main() { int t; cin>>t; while(t--) { int a,b; cin>>a>>b; if(a>b) swap(a,b); if(a*2==b) cout<<b*b<<endl; else { if(2*a>b) cout<<2*a*2*a<<endl; else cout<<b*b<<endl; } } }
B:http://codeforces.com/contest/1360/problem/B
题意:
将n个数分成两组,要求一组的最大值减去另一组的最小值的绝对值最小。
解析:
直接sort然后找最小间距
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const int maxn=1e3+10; int a[56]; int main() { int t; cin>>t; while(t--) { int n; cin>>n; int minn=1e9; for(int i=1;i<=n;i++) cin>>a[i]; sort(a+1,a+1+n); for(int i=2;i<=n;i++) minn=min(minn,a[i]-a[i-1]); cout<<minn<<endl; } }
C:http://codeforces.com/contest/1360/problem/C
题意:
给出n个数,要求进行两两配对,配对的两个数满足%2相等或者差值为1。
问是否能把所有数配对成功。
解析:
题中已经表示:n为偶数,所以偶数的数目和奇数的数目的奇偶性是相同的。
如果数目均为偶数,那么所有偶数内部配,奇数内部配,是可以包含所有数的。
如果数目均为奇数,那么遍历一下,是否存在差值为1的两个数,如果有,一定为一奇一偶,数目中把它俩划掉,也是正好可以进行两两配对的。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; int a[80]; int main() { int t; cin>>t; while(t--) { int n; cin>>n; int j=0,o=0,d=0; for(int i=1;i<=n;i++) { cin>>a[i]; if(a[i]%2!=0) j++; else o++; } sort(a+1,a+1+n); for(int i=2;i<=n;i++) { if(a[i]-1==a[i-1]) { d++; } } if(j%2==0&&o%2==0) cout<<"YES"<<endl; else { if(d>0) cout<<"YES"<<endl; else cout<<"NO"<<endl; } } }
D:http://codeforces.com/contest/1360/problem/D
题意:
给出n和k,在[1,k]中找到一个x,使得n%x==0而且n/x最小。
解析:
直接遍历的话会超时。既然是找n的因子,那么直接在sqrt(n)以内找就可以了,复杂度为O(sqrt(n))。
通过sqrt(n)左边因子来顺便判断右边
找到的每一个因子,要满足<=k,并不断更新x的最大值,就能保证n/x最小。
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; ll minn=1e9; int main() { int t; cin>>t; while(t--) { ll n,k; cin>>n>>k; minn=1e9; if(k>=n) cout<<"1"<<endl; else { ll maxx=0; for(ll i=1;i*i<=n;i++) { if(n%i==0&&i<=k) { if(n/i<=k) maxx=max(maxx,n/i); maxx=max(maxx,i); } } cout<<n/maxx<<endl; } } }
E:http://codeforces.com/contest/1360/problem/E
题意:
左边和上面发射炮弹,如果遇到阻碍,那么停住,标为1,而且上一个位置也标为1。给出一个情况,判定是否合法。
解析:
刚开始想复杂了,对于一个1来说,它的下方,要么是边界,要么是1,同理,它的右边也一样。
所以如果一个1的下方和右方满足其中一个条件,就是合法的。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 60; char mp[maxn][maxn]; int main() { int t; cin>>t; while(t--) { int n; cin>>n; for(int i=0;i<n;i++) cin>>mp[i]; int ok = 0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(i<n-1&&j<n-1&&mp[i][j]=='1') { if(mp[i+1][j]!='1'&&mp[i][j+1]!='1') { ok=1;break; } } } if(ok) cout<<"NO"<<endl; else cout<<"YES"<<endl; } }
F:http://codeforces.com/contest/1360/problem/F
题意:
给出n个字符串,是否存在一个串,与这n个字符串最多只有一个位置不相同。
解析:
直接暴力模拟
mp[1~n][1~m]记录每一个字符串。
s[i]记录第一个字符串的每一位。
以第一个字符串为基准,对它修改每一位,并check(),看是否合法:与其他字符串的不同位置数<=1
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 60; char mp[12][12]; char s[12]; int n , m ; bool check() { for(int i=1;i<n;i++) { int cnt=0; for(int j = 0 ; j < m ; j++) { if(mp[i][j]!=s[j]) cnt++; } if(cnt>1) return false; } return true; } int main() { int t; cin>>t; while(t--) { cin>>n>>m; for(int i=0;i<n;i++) cin>>mp[i]; for(int i=0;i<m;i++) s[i]=mp[0][i]; int ok = 1; for(int i=0;i<m;i++) { for(char j='a';j<='z';j++) { s[i]=j; if(check()) { ok=0; break; } } if(!ok) { // cout<<s<<"-"<<endl; break; } s[i]=mp[0][i]; //记得还原!因为每次只能修改一处 } // for(int i=0;i<m;i++) // cout<<s[i]; // cout<<endl; s[m]='