啓航組歡樂賽 題解

T1 買本子

這一道題咱們能夠考慮暴力分解:若是每個包裝所含本子的數量不能總共要買的本子數量整除的話,要買的包裝總數要多一,而後求出各包裝總共的錢數最後比大小便可。ios

#include<cstdio>
#include<cstring>
using namespace std;
int main(){
    int n, q, w, e, r, t, y, ans;
    scanf("%d %d%d %d%d %d%d",&n, &q, &r, &w, &t, &e, &y);
    if(n % q) q = (n / q) + 1;
    else q = n / q;
    
    if(n % w) w = (n / w) + 1;
    else w = n / w;
    
    if(n % e) e = (n / e) + 1;
    else e = n / e;
    
    q *= r;
    w *= t;
    e *= y;
    ans = q;
	if(ans > w) ans = w;
	if(ans > e) ans = e;
    printf("%d\n", ans);
    return 0;
}

T2 哥的八個猜測

專門開一個函數判斷質數,而後按照 \(i\)\(j\) 都是質數的條件暴力枚舉便可。c++

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
bool p(int num){
	for(int i = 2; i <= sqrt(num); i++)
		if(num % i == 0) return false;
	return true;
}
int main(){
	int n,i,j;
	cin >> n;
	for(i = 2; i <= n / 2; i++){
		j = n - i;
		if(p(i) && p(j)){
			cout << n << " = " << i << " + " << j << endl;
			break;
		}
	}return 0;
}

T3 成績排名

開一個結構體冒泡排序便可,也能夠寫一個cmp函數用sort。算法

#include<stdio.h>
struct jxj {
	int yw;
	int sx;
	int yy;
	int sum;
	int id;
};
int main() {
	struct jxj a[500],temp;
	int i,j,n;
	scanf("%d",&n);
	for(i=1; i<=n; i++) {
		scanf("%d%d%d",&a[i].yw,&a[i].sx,&a[i].yy);
		a[i].sum=a[i].yw+a[i].sx+a[i].yy;
		a[i].id=i;
	}
	for(i=1; i<n; i++)
		for(j=1; j<=n-i; j++) {
			if(a[j].sum<a[j+1].sum) {
				temp=a[j];
				a[j]=a[j+1];
				a[j+1]=temp;
			} else if(a[j].sum==a[j+1].sum&&a[j].yw<a[j+1].yw) {
				temp=a[j];
				a[j]=a[j+1];
				a[j+1]=temp;
			} else if(a[j].sum==a[j+1].sum&&a[j].yw==a[j+1].yw&&a[j].id>a[j+1].id) {
				temp=a[j];
				a[j]=a[j+1];
				a[j+1]=temp;
			}
		}
	for(i=1; i<=5; i++)
		printf("%d %d\n",a[i].id,a[i].sum);
	return 0;
}

T4 蛇形矩陣

純找規律題,簡單的按照行數分類討論一下便可。函數

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
using namespace std;
int main() {
	int n,i,j,k,t = 0;
	int a[21][21] = {0};
	cin >> n;
	for(k = 1; k <= n; k++){
		if(k % 2 == 0) {
            for(i = 1; i <= k; i++) {
				j = n - k + i;
				t++;
				a[i][j] = t;
				a[n + 1 - i][n + 1 - j] = n * n + 1 - t;
			}
        }else{ 
            for(i = k; i >= 1; i--) {
				j = n - k + i;
				t++;
				a[i][j] = t;
				a[n + 1 - i][n + 1 - j] = n * n + 1 - t;
			}
        }
	}
	for(i = 1; i <= n; i++) {
		for(j = 1; j <= n; j++)
			cout << setw(5) << a[i][j];
		cout << endl;
	}
	return 0;
}

T5 type

手寫一個字符棧,寫入就壓棧,刪除就彈棧。spa

#include<iostream>
#include<cstdio>
using namespace std;
int n,top;
char a[100001];
int main() {
	scanf("%d",&n);
	while(n--) {
		char ch[2];
		scanf("%s",ch);
		if(ch[0]=='T')cin>>a[++top];
		else if(ch[0]=='U') {
			int x;
			scanf("%d",&x);
			top-=x;
		} else {
			int x;
			scanf("%d",&x);
			cout<<a[x]<<endl;
		}
	}
	return 0;
}

T6 最優佈線問題

最小生成樹問題模板,直接跑一遍克魯斯卡爾便可。code

#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <iostream>

using namespace std;

int main() {
	int g[201][201];
	long long int minl[201];
	bool u[201];
	int n,i,j,k,tot;
	memset(g,0xffffff,sizeof(g));
	cin>>n;
	for (i = 1; i <= n; i++)
		for (j = 1; j <= n; j++)
			cin>>g[i][j];
	for (i = 2; i <= n; i++)
		minl[i] = 0x5ffffff;
	minl[1] = 0;
	minl[0] = 0x5ffffff;
	memset(u,true,sizeof(u));
	for (i = 1; i <= n; i++) {
		k = 0;
		for (j = 1; j <= n; j++)
			if ((u[j]) && (minl[j] < minl[k]))
				k = j;
		u[k] = false;
		for (j = 1; j <= n; j++)
			if ((u[j]) && (g[k][j] < minl[j]))
				minl[j] = g[k][j];
	}
	tot = 0;
	for (i = 1; i <= n; i++)
		tot += minl[i];
	printf("%d\n",tot);
	return 0;
}

T7 迷宮

直接跑一遍DFS就能得出答案。排序

#include<iostream>
#include<cstring>
using namespace std;
int n,s;
bool b[13][13];
const int dx[8]={0,0,1,1,1,-1,-1,-1},
          dy[8]={1,-1,1,0,-1,1,0,-1};

void go(int x,int y)
{
	if (x==1 && y==n){
		s++;
		return;
	}
	int i,xx,yy;
	for (i=0;i<=7;i++)
	{
		xx=x+dx[i];
		yy=y+dy[i];
		if (b[xx][yy])
		{
			b[xx][yy]=false;
			go(xx,yy);
			b[xx][yy]=true;
		}
	}
}
int main()
{
	int i,j,x;
	cin>>n;
	memset(b,0,sizeof(b));
	for (i=1;i<=n;i++)
	    for (j=1;j<=n;j++)
	    {
			cin>>x;
			b[i][j]=(x==0);
		}
	s=0;
	b[1][1]=false;
	go(1,1);
    cout<<s<<endl;
    return 0;
}

T8 S君的甜品店

Subtask 1:ip

直接暴力枚舉便可,預計得分 20 分。ci

Subtask 2:string

使用 \(O(n^3)\) 的算法枚舉出從 \(i\)\(j\) 的每一個區間(\(all_{i,j}\))而後用 \(dp_i=max(dp_i,dp_{j-1}+all_{j,i})\) 的狀態轉移方程求出最大值。

for(int i=1;i<=n;i++){
    for(int j=i;j<=n;j++){
        int f=1;
        for(int k=i;k<=j;k++)
            f=f*a[k]%19260817;
        all[i][j]=f;
    }
}
for(int i=1;i<=n;i++)
    for(int j=1;j<=i;j++)
        dp[i]=max(dp[i],dp[j-1]+all[j][i]);

預計得分50分。

Subtask 3:

咱們能夠發現一個性質,就是 \(all_{i,j}=all_{i,j-1}\times a_j\) ,便可以由前一個狀態轉移過來,咱們就能夠在 \(O(n^2)\) 的時間複雜度內預處理了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=19260817;
ll a[10005],dp[10005],all[10005][10005];
int main() {
	int n,f=1;
	cin>>n;
	for(int i=1; i<=n; i++) cin>>a[i];
	for(int i=1; i<=n; i++) {
		all[i][i]=a[i]%mod;
		for(int j=i+1; j<=n; j++)
			all[i][j]=all[i][j-1]*a[j]%mod;
	}
	for(int i=1; i<=n; i++) 
		for(int j=1; j<=i; j++) 
			dp[i]=max(dp[i],dp[j-1]+all[j][i]);
	printf("%lld\n",dp[n]);
}

值得一提的是,若是你不開 long long 的話,預計和暴力老哥同分哦~

相關文章
相關標籤/搜索