1. 程式人生 > 實用技巧 >晚間測試2 A. 裝飾 思維題

晚間測試2 A. 裝飾 思維題

題目描述



分析

一道思維題
顯然,\((a+b+c)/3\) 是答案的一個上界,\(a+b+c-max(a,b,c)\)也是答案的一個上
界,下面大致證明 \(min((a+b+c)/3,a+b+c-max(a,b,c))\)即為答案:
1、當\((a+b+c)/3 <= a+b+c-max(a,b,c)\)時,沒有哪一種顏色的氣球數量特別
地多,氣球數量的差距可以將三色氣球裝飾的桌子更換一個氣球來彌補,這樣就
可以裝飾\((a+b+c)/3\) 張桌子。
2、否則,不妨假設紅色氣球數量 \(a\) 很大,那麼這時候顯然可以裝飾出 \(b+c= a+b+c-max(a,b,c)\)張桌子(兩個紅色氣球與一個非紅色氣球)。
綜上所述,答案即為 \(min((a+b+c)/3,a+b+c-max(a,b,c))\)


直接模擬放的過程也可以

程式碼(模擬)

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
inline int read(){
	int x=0,fh=1;
	char ch=getchar();
	while(ch<'0' || ch>'9'){
		if(ch=='-') fh=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*fh;
}
int t,aa,bb,cc,cnt=0;
void msort(int &xx,int &yy,int &zz){
	if(xx<yy) std::swap(xx,yy);
	if(yy<zz) std::swap(yy,zz);
	if(xx<yy) std::swap(xx,yy);
}
int main(){
	freopen("decorate.in","r",stdin);
	freopen("decorate.out","w",stdout);
	t=read();
	while(t--){
		aa=read(),bb=read(),cc=read();
		cnt=0;
		while(1){
			msort(aa,bb,cc);
			if(aa==bb && bb==cc){
				cnt+=aa;
				break;
			} else if(aa==bb+1 && bb==cc){
				cnt+=cc;
				break;
			} else if(aa==bb && bb==cc+1){
				cnt+=cc;
				break;
			}
			if(aa<2 || bb<1) break;
			if(aa!=bb){
				if(bb==cc){
					int now=std::min((aa-bb)/3,bb);
					if(now==0){
						aa-=2,bb--;
						cnt++;
					} else {
						aa-=now*4;
						bb-=now;
						cc-=now;
						cnt+=now*2;
					}
				} else {
					int now=std::min(aa-bb,bb-cc);
					aa-=now*2,bb-=now;
					cnt+=now;
				}
			} else{
				int now=(aa-cc)/3;
				if(now==0 || aa<3){
					aa-=2;
					bb--;
					cnt++;
				} else {
					aa-=now*3;
					bb-=now*3;
					cnt+=now*2;
				}
			}
		}
		printf("%d\n",cnt);
	}
	return 0;

程式碼(結論)

#include <cstdio>
#include <cstring>
#include <algorithm>
const int N = 1e6 + 10;
int main() {
	freopen("decorate.in", "r", stdin);
	freopen("decorate.out", "w", stdout);
	int t;
	scanf("%d", &t);
	while(t--) {
		long long a, b, c;
		scanf("%lld%lld%lld", &a, &b, &c);
		printf("%lld\n", std::min((a + b + c) / 3, a + b + c - std::max(a, std::max(b, c))));
	}
	return 0;
}