Codeforces Round #579 (Div. 3)
打完这场心态蹦了...
A. Circle of Students
真的服了,就是这道这么简单的题卡了我半天。一开始还想到用最大最小表示法。最后发现找到最大最小值的下标,用正循环一次和逆循环一次判断即可。
完整代码;
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <deque> using namespace std; const int maxn = 300;int arr[maxn];int main(){ int T; cin>>T; while(T--){ int n,tmp; int flaga,flagb; flaga = flagb =1; cin>>n; memset(s,'\0',sizeof(s)); for(int i=0;i<n;i++){ cin>>arr[i]; } Min = find(arr,arr+n,1) - arr; Max = find(arr,arr+n,n) - arr; for(int i=0;i<n-1;i++){ if(arr[(Max+i+n)%n]-arr[(Max+i+1+n)%n]!=1) flaga = 0; } for(int i=0;i<n-1;i++){ if(arr[(Min+i+1+n)%n]-arr[(Min+i+n)%n]!=1) flagb = 0; } if(flaga||flagb) cout<<"YES"<<endl; else cout<<"NO"<<endl; } }
B. Equal Rectangles
题意:给你n个矩形的边(4n个),问你能否组成n个面积相同的矩形 (矩形的四个角均为直角)
思路:两两匹配,同时注意所给的不同边个数是否都为偶数,否则不能组成矩形
//还要判断所给出的相同个数是否为偶数,否则不能组成边
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <deque>
using namespace std;
const int maxn = 400+5;
const int maxm =1e4+1;
int arr[maxn];
int cont[maxm];
int main(){
int T;
int n;
cin>>T;
while(T--){
int n;
int flag = 0;
int cnt = 0;
cin>>n;
memset(arr,0,sizeof(arr));
memset(cont,0,sizeof(cont));
for(int i=1;i<=4*n;i++){
cin>>arr[i];
cont[arr[i]]++;
}
sort(arr+1,arr+4*n+1);
for(int i=1;i<=arr[4*n];i++){
if(cont[i]&1) flag = 1;
}
for(int i=1;i<=2*n;i++){
if(arr[i]*arr[4*n-i+1]!=arr[i+1]*arr[4*n-i]) flag = 1;
}
if(flag) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
}
C. 给你n个数(1<=n<=4e5)的序列, 然后叫你求该序列共同gcd的因子个数。
//啊,智力被爆了啊。还以为什么欧拉筛打表然后求gcd,结果直接求因子就行
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <deque>
#define IOS ios::sync_with_stdio(0); cin.tie(0);
#define ll long long
using namespace std;
const int maxm = 3e5+5;
const int maxn = 1.5e7+5;
int n;
int vis[maxn];
int p[maxn];
int cnt;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
int main(){
IOS
while(cin>>n){
ll g = 0;
ll tmp;
int cont = 0;
for(int i=0;i<n;i++){
cin>>tmp;
g = gcd(tmp,g);
}
int ans = 0;
tmp = g;
long long k;
for( k=1;k*k<=g;k++){
if(g%k==0&&g!=k*k){
ans += 2;
}else if(g%k==0&&g==k*k){
ans += 1;
}
}
cout<<ans<<endl;
}
}
E.boxer (贪心)
题意:给你一个长为n的序列,序列中的值可以 加1减1或者不变,求出通过改变后最多有多少个不同的值
思路:贪心(1) 先减1看是否以及存在 (2)在判断自身是否已经存在(3)加1判断是否存在 。实际上就是尽可能向下填满然后变比自己大的值
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <deque> #define IOS ios::sync_with_stdio(0); cin.tie(0); #define ll long long using namespace std; const int maxn =150000+5; int vis[maxn]; int arr[maxn]; int cont[maxn]; int cnt; int main(){ IOS int n; while(cin>>n){ cnt = 0; int tmp; for(int i=0;i<n;i++){ cin>>arr[i]; } sort(arr,arr+n); for(int i=0;i<n;i++){ if(cont[arr[i]]) cont[arr[i]+1]++; else if(cont[arr[i]-1]==0&&arr[i]>1) cont[arr[i]-1]++; else cont[arr[i]]++; } for(int i=1;i<=150005;i++){ if(cont[i]) cnt++; } cout<<cnt<<endl; } }