A:Circle of Students
直接模拟
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 203;
int a[maxn];
int main()
{
	int q;
	scanf("%d",&q);
	while(q--)
	{
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++) 
			scanf("%d",&a[i]);
		a[n+1]=a[1];
		if(n==1) {
			printf("YES\n");continue;
		}
		int flag=0,u=0,v=0;
		for(int i=2;i<=n;i++) 
			if(a[i]-a[i-1]==1) u++;
			else break;	
		for(int i=n+1;i>=2;i--) 
			if(a[i]-a[i-1]==1) v++;
			else break;
		if(u+v==n-1) {
			printf("YES\n");continue;
		}
		u=v=0;
		for(int i=2;i<=n;i++) 
			if(a[i]-a[i-1]==-1) u++;
			else break;	
		for(int i=n+1;i>=2;i--) 
			if(a[i]-a[i-1]==-1) v++;
			else break;
		if(u+v==n-1) {
			printf("YES\n");continue;
		}
		printf("NO\n");
	}
	return 0;
}
B: Equal Rectangles
分析:排序后最大乘最小等于矩形面积,判断一下即可
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1004;
int a[maxn];
map<int,int> mp;
ll max(ll a,ll b){return a>b?a:b;}ll min(ll a,ll b){return a<b?a:b;}
int main()
{
	int q;
	scanf("%d",&q);
	while(q--)
	{
		int n,flag=0;
		mp.clear();
		scanf("%d",&n);
		for(int i=1;i<=n*4;i++) {
			scanf("%d",&a[i]);
			mp[a[i]]++;
		}
		map<int,int>::iterator it = mp.begin();
		for(;it!=mp.end();it++) 
			if(((*it).second)%2==1) 
			{
				flag=1;break;	
			} 
		if(flag) {
			printf("NO\n"); continue;
		}
		sort(a+1,a+1+n*4);
		int l=1,r=n*4,s=a[1]*a[4*n];
		while(l<r) 
		{
			if(a[l]*a[r]!=s) 
			{
				flag=1;break;
			}
			l++;r--;
		}
		if(flag) printf("NO\n");
		else printf("YES\n");
	}
	return 0;
}
C: Common Divisors
分析: 求数列gcd后算gcd的因子数量
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll GCD(ll a,ll b)
{
	if(b==0) return a;else if(a==0) return b;
	return a%b==0?b:GCD(b,a%b); 
}
int main()
{
	int n; ll x,gcd=0,ans=0; 
	scanf("%d",&n);
	for(int i=1;i<=n;i++) {
		scanf("%I64d",&x);
		gcd=GCD(x,gcd);
	}
	for(ll i=1;i*i<=gcd;i++) 
	{
		if(gcd%i==0&&i*i!=gcd) ans+=2;
		else if(gcd%i==0&&i*i==gcd)ans++;
	}
	printf("%I64d",ans);
	return 0;
}
D1:Remove the Substring (easy version)
分析:数据很小,直接枚举要删除的substring
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
	string s,t;
	cin>>s>>t;
	int ans=0;
	for(int i=0;i<s.length();i++) for(int j=i;j<s.length();j++) 
	{
		int now=0;
		for(int k=0;k<s.length();k++) 
			if(k>=i&&k<=j) continue; 
			else if(t[now]==s[k]) {
				now++;
				if(now==t.length()) break;
			}
		if(now==t.length()) ans=max(ans,j-i+1);
	}
	cout<<ans;
	return 0;
}
D2:Remove the Substring (hard version)
分析:三种情况,(1)删除最左端一段(2)删除最右端一端(3)删除中间某一段。O(n)复杂度算出两个数组,l[maxn] 和 r[maxn],l[i]表示从s[0]到s[|s|-1]遍历t[i]最早出现的位置(即尽量靠左),r[i]表示从s[|s|-1]到s[0]遍历t[i]最早出现的位置(即尽量靠右)。对于(1),ans=r[0],对于(2),ans=|s| - l[|t| - 1]-1,对于(3),ans=max(r[i] - l[i-1] -1) { 1<=i<=|t|-1 }。取三种情况最大的
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 3;
int l[maxn],r[maxn];
int main()
{
	string s,t;
	cin>>s>>t;
	int ans=0;
	for(int i=0,j=0;i<s.length()&&j<t.length();i++) 
		if(s[i]==t[j]) l[j++]=i;
	for(int i=s.length()-1,j=t.length()-1;i>=0&&j>=0;i--)
		if(s[i]==t[j]) r[j--]=i;
	ans=max(r[0],int(s.length()-l[t.length()-1]-1));
	for(int i=1;i<s.length();i++)
		ans=max(ans,r[i]-l[i-1]-1);
	cout<<ans;
	return 0;
}
E: Boxers
分析:排序后用桶装一下
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 2;
int a[maxn],c[maxn];
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++) 
		scanf("%d",&a[i]);
	sort(a+1,a+1+n);
	for(int i=1;i<=n;i++) {
		if(a[i]-1==0)
		{
			if(!c[a[i]]) c[a[i]]=1;
			else c[a[i]+1]=1;
		}
		else{	
			if(!c[a[i]-1]) c[a[i]-1]=1;
			else if(!c[a[i]]) c[a[i]]=1;
			else c[a[i]+1]=1;
		}
	}
	int ans=0;
	for(int i=1;i<=150001;i++) if(c[i]) ans++;
	printf("%d",ans);
	return 0;
}
F1. Complete the Projects (easy version)
分析: 贪心排序后check一遍  (详见tutorial:https://codeforces.com/blog/entry/69108)
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 104;
struct node {
	ll a,b;
};
vector<node> c,neg;
bool cmp(const node &A,const node &B)
{
	return (A.a+A.b)>(B.a+B.b);
}
bool cmp2(const node &A,const node &B)
{
	return A.a<B.a;
}
int main()
{
	int n; ll r,x,y;
	scanf("%d%I64d",&n,&r);
	for(int i=1;i<=n;i++) {
		scanf("%I64d%I64d",&x,&y);
		if(y>=0) c.push_back({x,y});
		else neg.push_back({max(x,-y),y});
	}
	sort(c.begin(),c.end(),cmp2); 
	sort(neg.begin(),neg.end(),cmp);
	for(int i=0;i<c.size();i++) 
		if(r<c[i].a) {
			printf("NO"); return 0;
		}
		else r+=c[i].b;
	for(int i=0;i<neg.size();i++) 
		if(r<neg[i].a) {
			printf("NO"); return 0;
		} 
		else r+=neg[i].b;
	printf("YES");
	return 0;
}
F2. Complete the Projects (hard version)
分析: 贪心排序后背包 (详见tutorial:https://codeforces.com/blog/entry/69108)
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 60004;
struct node {
	ll a,b;
};
vector<node> c,neg;
int dp[maxn];
bool cmp(const node &A,const node &B)
{
	return A.a<B.a;
}
bool _cmp(const node &A,const node &B)
{
	return (A.a+A.b)<(B.a+B.b);
}
int main()
{
	int n,ans=0; ll r,x,y;
	cin>>n>>r;
	for(int i=1;i<=n;i++) {
		cin>>x>>y;
		if(y>=0) c.push_back({x,y});
		else neg.push_back({max(x,-y),y});
	}
	sort(c.begin(),c.end(),cmp);
	sort(neg.begin(),neg.end(),_cmp);
	for(int i=0;i<c.size();i++) 
		if(r<c[i].a) break;
		else {
			r+=c[i].b; ans++;
		}
	for(int i=0;i<neg.size();i++) for(ll j=r;j>=abs(neg[i].b);j--) 
		if(j>=neg[i].a&&j+neg[i].b>=0) dp[j]=max(dp[j],dp[j+neg[i].b]+1);
	ans+=dp[r];
	cout<<ans;
	return 0;
}