[SHGOI #2] 2023.9题解

T1:

这是一个简单的贪心算法问题。

首先,我们需要统计每个小学生所需的汉堡、炸鸡和可乐的数量,以及KFC老爷爷拥有的汉堡、炸鸡和可乐的数量。

然后,我们可以按照以下步骤进行计算:

  1. 初始化总收益为0。

  2. 对于每个小学生,判断KFC老爷爷是否能够满足他们的需求。如果满足,则将对应的汉堡、炸鸡和可乐数量减去KFC老爷爷拥有的数量,并将总收益增加相应的金额。

  3. 如果KFC老爷爷的汉堡、炸鸡或可乐数量不足以满足某个小学生的需求,我们可以尽量满足他们的需求,直到KFC老爷爷的汉堡、炸鸡或可乐数量为0。这样可以最大程度地提高总收益。

  4. 最后,输出总收益即可。

       PS:由于时限只有200ms,建议卡常加吸氧         

#include <bits/stdc++.h>
using namespace std;
struct node {
	int aa[1010];
	int n;
};
node a, b, c;
int m;
int f[110][110][110];
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> m >> a.n >> b.n >> c.n;
	
	for ( register int i = 0; i < m; ++i ) cin >> a.aa[i] >> b.aa[i] >> c.aa[i];
	
	for ( register int i = 0; i < m; ++i )
		for ( register int j = a.aa[i]; j <= a.n; ++j )
			for ( register int k = b.aa[i]; k <= b.n; ++k )
				for ( register int l = c.aa[i]; l <= c.n; ++l )
					if(f[j][k][l]< f[j - a.aa[i]][k - b.aa[i]][l - c.aa[i]] + 15)[[likely]]
						f[j][k][l] = f[j - a.aa[i]][k - b.aa[i]][l - c.aa[i]] + 15;
						
						cout << f[a.n][b.n][c.n];
}

        T2:

F1:

这是一个博弈论的问题。我们可以使用动态规划来解决。

设dp[i][j]表示在石子序列a的第i个到第j个石子之间,先手的玩家(zyh)能够获得的最大数字和与后手的玩家(wqc)的数字和之差。

根据题目要求,zyh先手,wqc后手,我们可以得到以下状态转移方程:

dp[i][j] = max(a[i] - dp[i+1][j], a[j] - dp[i][j-1])

其中,a[i]表示第i个石子的数字。

我们可以从小到大计算dp数组,最终dp[1][n]的值即为zyh和wqc的数字和之差。

具体实现时,我们可以使用一个二维数组dp来保存中间结果,初始化为0。然后使用两层循环,外层循环遍历石子序列的长度,内层循环遍历石子序列的起始位置。根据状态转移方程更新dp数组的值。最后输出dp[1][n]的值。

F2:

#include<iostream>
#include<iomanip>
#include<cstring>
#include<stack>
#include<vector>
#include<string>
#include<map>
#include<cstdlib>
#include<queue>
#include<math.h>
#include<time.h>
#include<set>
#include<cstdio>
#include<algorithm>
using namespace std; 
using std::cin;
using std::cout;
using std::endl;
namespace IN{
	const int MAX_INPUT = 1000000;
#define getc() (p1==p2&&(p2=(p1=buf)+inbuf->sgetn(buf,MAX_INPUT),p1==p2)?EOF:*p1++)
	char buf[MAX_INPUT],*p1,*p2;
	template<typename T>inline bool read(T &x) {
		static std::streambuf *inbuf=cin.rdbuf();
		x=0;
		register int f=0,flag=false;
		register char ch=getc();
		while(!isdigit(ch)){
			if (ch=='-') f=1;
			ch=getc();
		}
		if(isdigit(ch)) x=x*10+ch-'0',ch=getc(),flag=true;
		while(isdigit(ch)) {
			x=x*10+ch-48;
			ch=getc();
		}
		x=f?-x:x;
		return flag;
	}
	template<typename T,typename ...Args>inline bool read(T& a,Args& ...args) {
		return read(a)&&read(args...);
	}
#undef getc
}

namespace OUT{
	template<typename T>inline void put(T x){
		static std::streambuf *outbuf=cout.rdbuf();
		static char stack[21];
		static int top=0;
		if(x<0){
			outbuf->sputc('-');
			x=-x;
		}
		if(!x){
			outbuf->sputc('0');
			outbuf->sputc('\n');
			return;
		}
		while(x){
			stack[++top]=x%10+'0';
			x/=10;
		}
		while(top){
			outbuf->sputc(stack[top]);
			--top;
		}
		outbuf->sputc('\n');
	}
	inline void putc(const char ch){
		static std::streambuf *outbuf=cout.rdbuf();
		outbuf->sputc(ch);
	}
	inline void putstr(string s){
		for(register int i=0;i<s.length();i++) putc(s[i]);
	}
	template<typename T>inline void put(const char ch,T x){
		static std::streambuf *outbuf=cout.rdbuf();
		static char stack[21];
		static int top = 0;
		if(x<0){
			outbuf->sputc('-');
			x=-x;
		}
		if(!x){
			outbuf->sputc('0');
			outbuf->sputc(ch);
			return;
		}
		while(x){
			stack[++top]=x%10+'0';
			x/=10;
		}
		while(top){
			outbuf->sputc(stack[top]);
			--top;
		}
		outbuf->sputc(ch);
	}
	template<typename T,typename ...Args> inline void put(T a,Args ...args){
		put(a);put(args...);
	}
	template<typename T,typename ...Args> inline void put(const char ch,T a,Args ...args){
		put(ch,a);put(ch,args...);
	}
}
using namespace IN;
using namespace OUT;
int main() {
	register int t;
	read(t);
	while(t--) {
		register int n;
		register int a[2];
        a[0]
=a[1]=0;		register int flag = true;
		read(n);
		while(n--) {
			flag = 1^flag;
			register int c;
			read(c);
			a[flag]+=c;
		}
		if(a[0]^a[1])
		cout<<"Win "<<abs(a[0]-a[1]);
		else cout<<"Draw 0";
		cout<<endl;
	}
	return 0;
}

这段代码是一个简单的游戏逻辑实现。代码首先读入一个整数t,表示游戏的轮数。然后进入一个循环,每一轮读入一个整数n,表示该轮游戏中的操作次数。接下来,循环n次,每次读入一个整数c,表示该次操作的值。然后根据奇偶性判断该次操作的值应该累加到a[0]还是a[1]中。最后根据a[0]和a[1]的差值输出游戏结果。

具体的逻辑如下:

  1. 读入整数t,表示游戏的轮数。
  2. 进入一个循环,循环t次。
  3. 在每一轮中,首先读入一个整数n,表示该轮游戏中的操作次数。
  4. 初始化a[0]和a[1]为0。
  5. 进入一个循环,循环n次。
  6. 在每一次循环中,首先判断flag的值,如果为true,则将c累加到a[0]中;如果为false,则将c累加到a[1]中。
  7. 根据flag的值取反,即1^flag,更新flag的值。
  8. 输出游戏结果,如果a[0]和a[1]的差值不为0,则输出"Win "和差值的绝对值;如果差值为0,则输出"Draw 0"。
  9. 输出换行符。
  10. 结束循环,返回0。

总体来说,这段代码实现了一个简单的游戏逻辑,根据不同的操作值累加到不同的变量中,并根据累加结果输出游戏结果。

T3:

题目要求实现一个简易计算器,可以计算给定的算式。算式包含加减乘除、幂运算、对数、三角函数等操作。

思路如下:

  1. 首先,解析输入的算式,将其转化为一个可以计算的表达式。可以使用栈来实现这一步骤。

  2. 然后,计算表达式的值。可以使用逆波兰表达式来计算。

  3. 最后,输出计算结果。

具体实现步骤如下:

  1. 创建一个栈,用于存储操作符和操作数。

  2. 遍历输入的算式,对于每个字符:

    • 如果是数字,将其转化为数字并入栈。

    • 如果是操作符,将其入栈。

    • 如果是右括号,弹出栈中的操作符和操作数,直到遇到左括号。将弹出的操作符和操作数组合成一个表达式,并将其结果入栈。

  3. 遍历结束后,栈中只剩下一个元素,即为计算结果。

  4. 输出计算结果。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值