1. 程式人生 > >2016ACM/ICPC亞洲區大連站-重現賽 4F組合(pro.D+pro.H+pro.I+pro.J)

2016ACM/ICPC亞洲區大連站-重現賽 4F組合(pro.D+pro.H+pro.I+pro.J)

已知:\left\{\begin{matrix} x+y=a \\ lcm(x,y)=b \end{matrix}\right. ( lcm(x,y) 代表x和y的最小公倍數),求x和y的值。

設x*y=k*b,k即為gcd(x,y),即\left\{\begin{matrix} x+y=a \\ x*y=k*b \end{matrix}\right.(1)==\left\{\begin{matrix} \frac{x}{k}+\frac{y}{k}=\frac{a}{k} \\ \frac{x}{k}*\frac{y}{k}=\frac{b}{k} \end{matrix}\right.

因為\frac{x}{k},\frac{y}{k}互質,則其和與積也互質,即k=gcd(a,b),則k已知,計算方程組(1)即可,詳見程式碼。

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;

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

int main(){
	ll a,b;
	while(~scanf("%lld%lld",&a,&b)){
		ll k=gcd(a,b);
		b*=k;
		ll tmp=sqrt(a*a-4*b);
		ll x=(a+tmp)/2;
		ll y=(a-tmp)/2;
		if(x>y) swap(x,y);
		if(x*y!=b)
			printf("No Solution\n");
		else printf("%lld %lld\n",x,y);
	}
	return 0;
}

遊戲有k個黑球,1個紅球,拿到紅球即勝利,計算先手是否有優勢贏遊戲。

先手拿到紅球的概率P為:

k=1:  P=\frac{1}{2}    ans=0

k=2:  P=\frac{1}{3}+\frac{2}{3}*\frac{1}{2}=\frac{2}{3}    ans=1

k=3:  P=\frac{1}{4}+\frac{3}{4}*\frac{2}{3}*\frac{1}{2}=\frac{1}{2}   ans=0

k=4: P=\frac{1}{5}+\frac{4}{5}*\frac{3}{4}*(\frac{1}{3}+\frac{2}{3}*\frac{1}{2})=\frac{1}{5}+\frac{2}{5}=\frac{3}{5}  ans=1

k=5: P=\frac{1}{6}+\frac{5}{6}*\frac{4}{5}*(\frac{1}{4}+\frac{3}{4}*\frac{1}{2})=\frac{1}{6}+\frac{2}{6}=\frac{1}{2}  ans=0

……

可以發現當k為奇數時先手無優勢,當k為偶數時有優勢。

#include<cstdio>

int main(){
	int k;
	while(~scanf("%d",&k)){
		if(k&1) printf("0\n");
		else printf("1\n");
	}
	return 0;
}

給出多邊形中每個三角形的頂角,求多邊形面積,只要求出每個三角形面積求和即可。

注意sin()裡的是弧度值,要先把角度轉換為弧度

#include<cstdio>
#include<cmath>
#define PI 3.1415927

int main(){
	int n,r;
	while(~scanf("%d%d",&n,&r)){
		double tmp=0;
		while(n--){
			double deg;
			scanf("%lf",&deg);
			tmp+=0.5*r*r*sin(deg*PI/180);
		}
		printf("%.3lf\n",tmp);
	}
	return 0;
}

給n個數,每個數都可以拆開成一個32位的2進位制

每8位一個位元組 ,每個位元組的2進位制數換算成十進位制時有多少個97,見程式碼

#include<cstdio>

int main(){
	int n;
	while(~scanf("%d",&n)){
		int ans=0;
		while(n--){
			int val;
			scanf("%d",&val);
			if(val==0) continue;
			while(val){
				if(val%(1<<8)==97) ans++;
				val/=(1<<8);
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}