2016 ICPC 大连

A Wrestling Match

判断二分图,特判没属性的孤点。

#include <bits/stdc++.h>
using namespace std;
const int maxn=1050;
vector<int> e[maxn];
int n,m,x,y;
int colour[maxn];
int du[maxn];
int vis[maxn];
bool dfs(int v,int c) {
	colour[v]=c;
	for(int i=0;i<(int)e[v].size();i++) {
		if(colour[e[v][i]]==c) {
			return false;
		}
		if(colour[e[v][i]]==0&&!dfs(e[v][i],-c))
			return false;
	}
	return true;
}
int main(){
	while(scanf("%d%d%d%d",&n,&m,&x,&y)!=EOF){
		for(int i=0;i<=n;i++) e[i].clear();
		memset(du,0,sizeof du);
		while(m--){
			int u,v;
			scanf("%d%d",&u,&v);
			e[u].push_back(v);
			e[v].push_back(u);
			du[u]++;du[v]++;
		}
		memset(colour,0,sizeof(colour));
		memset(vis,0,sizeof vis);
		bool ptd=0;
		for(int i=1;i<=x;i++){
			int x;
			scanf("%d",&x);
			colour[x]=1;
			vis[x]=1;
		}
		for(int i=1;i<=y;i++){
			int x;
			scanf("%d",&x);
			colour[x]=-1;
			if(vis[x]==1){
				ptd=1;
				break;
			}
			vis[x]=-1;
		}
		if(ptd){
			puts("NO");
			continue;
		}
		for(int i=1;i<=n;i++){
			if(vis[i]==0 && du[i]==0){
				puts("NO");
				ptd=1;
				break;
			}
		}
		if(ptd)continue;
		bool flag=true;
		for(int i=1;i<=n && flag;i++){
			if(colour[i]==1) flag=dfs(i,1);
			else if(colour[i]==-1) flag=dfs(i,-1);
		}
		for(int i=1;i<=n && flag;i++){
			if(colour[i]==0) flag=dfs(i,1);
		}
		// for(int i=1;i<=n;i++)
		// 	printf("%d ",colour[i]);
		// puts("");
		for(int i=1;i<=n;i++){
			if(colour[i]==0){
				flag=false;
				break;
			}
		}
		if(flag) puts("YES");
		else puts("NO");
	}
	return 0;
}

C Game of Taking Stones

威佐夫博弈
求$frac{sqrt(5)+1}{2}b$。

import java.util.*;
import java.math.*;

public class Main{
	
	public static void main(String[] args){
		Scanner cin = new Scanner(System.in);
		BigDecimal k = null;
		BigDecimal eps = BigDecimal.valueOf(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001);
		BigDecimal l=BigDecimal.valueOf(1.0);
		BigDecimal r=BigDecimal.valueOf(3.0);
		BigDecimal Five=BigDecimal.valueOf(5.0);
		for(int i=1;i<=2000;i++){
			BigDecimal mid=l.add(r);
			mid=mid.divide(BigDecimal.valueOf(2.0));
			BigDecimal p = mid.multiply(mid);
			int pk = p.compareTo(Five);
			if(pk<=0){
				l=mid.add(eps);
				k=mid;
			} else {
				r=mid.subtract(eps);
			}
		}
		//System.out.println(k);
		k=k.add(BigDecimal.valueOf(1.0));
		k=k.divide(BigDecimal.valueOf(2.0));
		BigDecimal a,b;
		while(cin.hasNext()){
			a=cin.nextBigDecimal();b=cin.nextBigDecimal();
			int pk=a.compareTo(b);
			if(pk<0){
				BigDecimal tmp = a;
				a=b;
				b=tmp;
			}
			BigDecimal ans = a.subtract(b);
			ans=ans.multiply(k);
			ans=ans.subtract(b);
			pk = ans.compareTo(BigDecimal.valueOf(1.0));
			int pt=ans.compareTo(BigDecimal.valueOf(0.0));
			if(pk<0 && pt>=0) System.out.println(0);
			else System.out.println(1);
		}
	}
}

D A Simple Math Problem

设$G=gcd(a,b)$。
$gcd(a,b)=gcd(x+y,lcm(x,y))=gcd(x+y,ky)=gcd(x+y,y)=gcd(x,y)$
那么等式$frac{x}{G}+frac{y}{G}=frac{a}{G}$。
$lcm(x,y)=frac{xy}{gcd(x,y)}$,
$frac{x}{G}frac{y}{G}=frac{b}{G}$.

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a % b);
}

ll a, b, x, y;

ll getsqrt(ll a){
	if(a==0) return 0;
	ll l=1,r=1e9;
	while(l<=r){
		ll mid = (l+r)/2;
		ll p=mid*mid;
		if(p==a)
			return mid;
		if(p<a)
			l=mid+1;
		if(p>a)
			r=mid-1;
	}
	return -1;
}

int main() {
	//freopen("in.txt","r",stdin);
	while (~scanf("%lld%lld", &a, &b)) {
		ll G = gcd(a, b);
		ll aa = a / G;
		ll bb = b / G;
		ll d = aa * aa - 4ll * bb;
		if(d<0){
			puts("No Solution");
			continue;			
		}
		ll t = getsqrt(d);
		//cout<<t<<endl;
		if(t==-1){
			puts("No Solution");
			continue;
		}
		ll ans1=(aa-t)/2;
		ll ans2=(aa+t)/2;
		if(ans1*2ll!=aa-t){
			puts("No Solution");
			continue;
		}
		ans1*=G;
		ans2*=G;
		if(ans1>ans2) swap(ans1,ans2);
		if(ans1<=0 || ans2>a){
			puts("No Solution");
			continue;			
		}
		printf("%lld %lld
",ans1,ans2);
	}
	return 0;
}

F Detachment

连续整数相乘时值很大。考虑到1没有贡献,那么必然是从2开始。
5=2+3
9=2+3+4
14=2+3+4+5
....
这些是分界。
多余的时候挂在末尾,都加1就行。
预处理fac和inv。

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const int maxn = 1e5 + 5;
const int N = 1e5;
ll fac[maxn];
ll inv[maxn];
ll S[maxn];

inline ll power(ll a, ll n, ll p) {
	ll ret = 1; ll now = a;
	while (n != 0) {
		if (n & 1)
			ret = ret * now % p;
		now = now * now % p;
		n >>= 1;
	}
	return ret;
}

void init() {
	fac[0] = 1;
	for (ll i = 1; i <= N; i++)
		fac[i] = fac[i - 1] * i % mod;
	inv[N] = power(fac[N], mod - 2, mod);
	for (ll i = N; i >= 1; i--)
		inv[i - 1] = inv[i] * i % mod;
	S[2]=2;
	for(ll i=3;i<=N;i++)
		S[i]=S[i-1]+i;
}

int main() {
	init();
	int t;
	ll n;
	scanf("%d", &t);
	while (t--) {
		scanf("%lld", &n);
		if (n <= 4) {
			printf("%lld
", n);
			continue;
		}
		ll x;
		ll l = 2, r = N;
		while (l <= r) {
			ll mid = (l + r) / 2;
			if ( S[mid] <= n) {
				l = mid + 1;
				x = mid;
			} else {
				r = mid - 1;
			}
		}
		x--;
		ll avg = n / x;
		ll ans = 1;
		if (x & 1) {
			ll k = x / 2;
			ll left = avg - k;
			ll right = avg + k;
			ll sum = (left + right) * x / 2;
			ll tmp = n - sum;
			while (tmp >= x) {
				tmp -= x;
				left++;
				right++;
			}
			if (tmp == 0) {
				ans = fac[right] * inv[left - 1] % mod;
			} else {
				ll lright = right - tmp;
				right++;
				ans = fac[lright] * inv[left - 1] % mod * fac[right] % mod * inv[lright + 1] % mod;
			}
		} else {
			ll k = x / 2;
			ll left = avg - k;
			ll right = avg + k - 1;
			ll sum = (left + right) * x / 2;
			ll tmp = n - sum;
			while (tmp >= x) {
				left++; right++;
				tmp -= x;
			}
			if (tmp == 0) {
				ans = fac[right] * inv[left - 1] % mod;
			} else {
				ll lright = right - tmp;
				right++;
				ans = fac[lright] * inv[left - 1] % mod * fac[right] % mod * inv[lright + 1] % mod;
			}
		}
		printf("%lld
", ans % mod);
	}
	return 0;
}

H To begin or not to begin

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main(){
	//freopen("in.txt","r",stdin);
	int n;
	while(~scanf("%d",&n))
		printf("%d
",(n+1)%2);
	return 0;
}

I Convex

#include <bits/stdc++.h>

using namespace std;
const int maxn=20;
const  double pi=acos(-1);
int a[1111];
int main() {
	int n,d;
	while(scanf("%d%d",&n,&d)!=EOF) {
		for(int i=1;i<=n;i++) {
			scanf("%d",&a[i]);
		}
		double ans = 0.0;
		for(int i=1;i<=n;i++) {
			ans+=0.5*d*d*sin(a[i]*pi/180.0);
		}
		printf("%.3lf
",ans);
	}
	return 0;
}

J Find Small A

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main(){
	//freopen("in.txt","r",stdin);
	int x,n;
	while(~scanf("%d",&n)){
		int cnt = 0;
		for(int i=1;i<=n;i++){
			scanf("%d",&x);
			while(x){
				if(x % 256 == 97)
					cnt++;
				x/=256;
			}
		}
		cout<<cnt<<endl;
	}
	return 0;
}
原文地址:https://www.cnblogs.com/foreignbill/p/7875798.html