春花秋月何时了,往事知多少

距离上次发题解已经过去快两个月了,这两月都在忙期末考试,最近终于告一段落,打算好好写写题解和补补题。

这场的感觉就是前三不难,第四题有些理解上的问题,导致浪费了不少时间(其实给时间第5题也开不出来^-^)


A. 彩虹糖的梦

每一位小朋友都想要吃到全部七种颜色的彩虹糖,那就是7种糖中最小的那种

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
void solve() {
	LL a[8];
	for(int i=1;i<=7;i++) cin>>a[i];
	LL mx = 1e18;
	for(int i=1;i<=7;i++){
		mx = min(mx,a[i]);
	}
	cout<<mx<<endl;
}
int main() {
    std::ios::sync_with_stdio(false), 
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int t = 1;
    while (t--){
        solve();
    }
    return 0;
}

B. 球格模型(简单版)

我的思路是分类讨论,因为k的个数一定要填满n,m中的最大值,所以当K<max(n,m)的时候,就输出-1, 其他情况下,就按照对角线填充,然后长的边填1,最后一位就填k减去前面多出来的数字。

写的石山-_-

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
void solve() {
	LL n,m,k;
	cin>>n>>m>>k;
	if(n==m){
		if(k<n){
			cout<<-1<<endl;
		}
		else{
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(i==j){
						if(i==n && j==m){
							cout<<k-n+1<<" ";
						}
						else{
							cout<<1<<" ";
						}
					}
					else {
						cout<<0<<" ";
					}
				}
				cout<<endl;
			}
		}
	}
	else if(n>m){
		if(k<n){
			cout<<-1<<endl;
		}
		else{
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(i>m){
						if(j==1){
							if(i==n){
								cout<<k-n+1<<" ";
							}
							else{
								cout<<1<<" ";
							}
						}
						else{
							cout<<0<<" ";
						}
					}
					else{
						if(i==j){
							cout<<1<<" ";
						}
						else{
							cout<<0<<" ";
						}
					}
				}
				cout<<endl;
			}

		}
	}
	else if(n<m){
		if(k<m){
			cout<<-1<<endl;
		}
		else{
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(j>n){
						if(i==1){
							if(j==m){
								cout<<k-m+1<<" ";
							}
							else{
								cout<<1<<" ";
							}
						}
						else{
							cout<<0<<" ";
						}
					}
					else{
						if(i==j){
							cout<<1<<" ";
						}
						else{
							cout<<0<<" ";
						}
					}
				}
				cout<<endl;
			}

		}
	}
}
int main() {
    std::ios::sync_with_stdio(false), 
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int t = 1;
    while (t--){
        solve();
    }
    return 0;
}


C.小数字

其实观察一下就能发现,开根号始终要比除2来的划算,或是说下降的更快,当数字到2的时候,三个方案就一样快了,都是减一,由于负数对1,3方案都不如2方案减得快,所以当n<=2的时候,就减去操作数m就可以了。

若是n>2,就直接用开根号来操作,直到n=2,减去剩余操作数m,如果m提前使用完了,就是最小的n。

要注意上取整

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
void solve() {
	LL n,m;
	cin>>n>>m;
	if(n<=2){
		cout<<n-m<<endl;
	}
	else{
		int p = 0;
		while(m){
			double c = sqrt(n);
			if(c==int(sqrt(n))) n = sqrt(n);
			else n = sqrt(n) + 1;
			m--;
			if(n==2) {
				p = 1;
				break;
			}
		}
		if(p==1){
			cout<<2-m<<endl;
		}
		else{
			cout<<n<<endl;
		}
	}
}
int main() {
    std::ios::sync_with_stdio(false), 
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int t;
    cin>>t;
    while (t--){
        solve();
    }
    return 0;
}

D.预知

这是第四题也是逆天,题目读假了,卡了半天

实际上分不同的情况:1.当如果种类都是1的话,就无需预知了,随便拿都是包赢的。

2.如果次大值是1,那么就是输出最大值-1

3.不然的话就是输出最大值

写的有些乱乱的

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
void solve() {
	int n;
	cin>>n;
	vector<LL> a(n+1,0);
	for(int i=1;i<=n;i++) cin>>a[i];
	if(n==1){
		cout<<-1<<endl;
	}
	else{
		sort(a.begin(),a.end());
		LL sum  = 0;
		int op = 0;
		for(int i=1;i<=n;i++){
			if(a[i]!=1) op=1;
			sum+=a[i];
		}
		if(op==0){
			cout<<0<<endl;
			return;
		}
		LL ans = 0;
		int qq = 0;
		for(int i=1;i<=n;i++){
			if(a[i]==1) continue;
			else{
				qq = i;
				break;
			}
		}
		ans+=a[qq]-1;
		for(int i=qq+1;i<=n;i++){
			ans+=a[i];
		}
		cout<<min(ans,a[n])<<endl;
	}
}
int main() {
    std::ios::sync_with_stdio(false), 
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int t;
    cin>>t;
    while (t--){
        solve();
    }
    return 0;
}