20201104大模拟(一)

20201104大模拟(一)

开错题了我吐了,赛后A一发过,绝了

B是什么deng西,我得有一段时间不想看到植物大战僵尸了,有一些边界问题

C是在计算的过程中的大模拟

D是思维,

总体来说其实还好,不要怕的,就还好

“一道题WA了五发以上其实就没有出的必要了”

自己想想为什么会打成这个样子好不好


A - Try and Catch

A

题目真的有点长,还是要耐心阅读理解吧,

只有一个throw,刚开始以为有好多,并且觉得空格挺难搞的就先没做,其实没啥坑的直接冲就完事

#include <bits/stdc++.h>
using namespace std;

struct node {
	int pos1;
	int pos2;
	string a;
	string b;
};

stack<int> tryy;
vector<node> catchh; 

string throww = "";
int idx;

bool cmp(node x, node y) {
	return x.pos1 < y.pos1;
}

int main() {
	int n;
	cin >> n;
	getchar();
	for(int i = 1; i <= n; ++ i) {
		string s;
		getline(cin, s);
		
		int len = s.length();
		
		for(int j = 0; j < len; ++ j) {
			if(s[j] == ' ') continue;
			if(s[j] == 't') {
				if(s[j + 1] == 'r') { // try
					tryy.push(i);
				}
				else { // throw
					int k = j + 1;
					for(; k < len; ++ k) {
						if(s[k] == '(') break;
					}
					++ k;
					
					for(; k < len; ++ k) {
						if(s[k] != ' ') break;
					}
					
					for(; k < len; ++ k) {
						if(s[k] == ' ' || s[k] == ')') break;
						throww = throww + s[k];
					}
					
					idx = i;
				}
				
				break;
			}
			if(s[j] == 'c') { // catch
				string aa = "";
				
				int k = j + 1;
				for(; k < len; ++ k) {
					if(s[k] == '(') break;
				}
				++ k;
				for(; k < len; ++ k) {
					if(s[k] != ' ') break;
				}
				
				for(; k < len; ++ k) {
					if(s[k] == ' ' || s[k] == ',') break;
					aa = aa + s[k];
				}
				
				string bb = "";
				
				for(; k < len; ++ k) {
					if(s[k] == '\"') break;
				}
				++ k;
				
				for(; k < len; ++ k) {
					if(s[k] == '\"') break;
					bb = bb + s[k];
				}
				
				//cout << i << " " << aa << " " << bb << endl;
				
				int pos1 = tryy.top();
				tryy.pop();
				catchh.push_back({pos1, i, aa, bb});
				
				break;
			}
		}
	}
	
	sort(catchh.begin(), catchh.end(), cmp);
	
	int siz = catchh.size();
	
	
//	cout << "---- catchh :\n" ; 
//	for(auto x : catchh) {
//		cout << x.pos1 << " " << x.pos2 << " " << x.a << " " << x.b << endl;
//	}
//	
//	cout << "\n\n";
//	cout << "idx :" << idx << endl;
 	
 	bool f = 0;
 	
 	for(int i = siz - 1; i >= 0; -- i) {
 		if(f) break;
 		node tmp = catchh[i];
 		
 		//cout << tmp.pos1 << " " << tmp.pos2 << endl;
 		if(tmp.pos1 < idx && tmp.pos2 > idx) {
 			//cout << throww << " " << tmp.a << endl; 
 			//cout << (tmp.a == throww) << endl;
 			if(tmp.a == throww) {
 				cout << tmp.b ;
 				f = 1;
 				break;
			}
		}
	}
	
	if(!f) {
		cout << "Unhandled Exception";
	}
	
	return 0;
}

B - I, zombie

植物大战僵尸,开错题目了,

一些边界问题

  • 第一个是土豆雷(这个赛时就想到了(比较后面才想到的
  • 有五十多个豌豆射手,或者说对于僵尸的血量可以是负的这件事的理解上面,是知道的,但是在处理过程中有个地方漏掉了,(

刚开始的思路是模拟每一段,每一段要么是MPPPPPPP 要么是MMMMM 就大概是两种,还有一些特殊情况比如PPPPP,但是其实可以归进去

对于每一段,他的左边有多少个豌豆,当前段要走几步什么的进行模拟(二分

但是关于僵尸血量可以是负的这件事,感觉可以换一种思路进行模拟,

还是要二分

最后一个位置是直接到达的,其他所有位置都要先走一步才能到达

MPMPMPMPMPMPMPM
12

60个豌豆还是处理错了

PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPMMMMMMMMMM
82

还是上面这个60个豌豆的样例,如果是前面全是P, 尸体可以骗土豆雷,但是去吃脑子的时候不能是尸体~~((?? 有点不确定了,~~(对的,但是不是这里的问题

这是第二次重码了,准备开始第三次

WA 也许哪天有心情可以改一改

#include <bits/stdc++.h>
using namespace std;

const int maxn = 110;
int sum[maxn];

bool judge(int leff, int p, int x, bool f) {
	if(x == 0) return 0;
	//if(p == 0) return 1;
	if(!f) {
		int z = x;
		int hp = 50;
		
		if(p) {
			for(int i = p; i > 0; -- i) {
				hp -= leff + i;
				if(hp <= 0) {
					z --;
					hp = 50;
				}
				if(z <= 0) return 0;
				
				int pea = 10;
				while(pea > 0) {
					pea -= z;
					hp -= leff + i;
					if(hp <= 0){
						z --;
						hp = 50;
					}
					if(z <= 0) return 0;
				}
			} 	
		}
		else {
			if(x >= 2) return 1;
			else return 0;
		}
		
		
	}
	else {
		int z = x;
		int hp = 50;
		
		
		if(p) {
			int pea = 10;
			while(pea > 0) {
				pea -= z;
				hp -= leff + p;
				if(hp <= 0){
					z --;
					hp = 50;
				}
				if(z <= 0) return 0;
			}	
		}
		else {
			if(x) return 1;
			else return 0;
		}
		
		for(int i = p - 1; i > 0; -- i) {
			hp -= leff + i;
			if(hp <= 0) {
				z --;
				hp = 50;
			}
			if(z <= 0) return 0;
			
			int pea = 10;
			while(pea > 0) {
				pea -= z;
				hp -= leff + i;
				if(hp <= 0){
					z --;
					hp = 50;
				}
				if(z <= 0) return 0;
			}
		} 
	}
	
	return 1;
}

int main () {
	int T;
	cin >> T;
	int cas = 0;
	while(T --) {
		++ cas;
		printf("Case %d: ", cas);
		string s;
		cin >> s;
		
		int n = s.size();
		if(s[0] == 'P') sum[0] = 1;
		else sum[0] = 0;
		
		for(int i = 1; i < n; ++ i) {
			sum[i] = sum[i - 1] + (s[i] == 'P' ? 1 : 0);
		}
		
		bool f = 1; 
		int cntp = 0;
		int tot = 0;
		
		for(int i = n - 1; i >= 0; -- i) {
			if(s[i] == 'M') {
				cout << "--------- cntp :" << cntp << ' ' << f << endl;
				int l = 0, r = 200000, ans;
				while(l <= r) {
					int mid = (l + r) >> 1;
					if(judge(sum[i], cntp, mid, f)) {
						ans = mid;
						r = mid - 1;
					}
					else {
						l = mid + 1;
					}
				}
				cout << ans << endl; 
				tot += ans;
				f = 0;
				cntp = 0;
			}
			else {
				cntp ++;
			}
		}
		
		//cout << tot << endl;
		
		//cout << cntp << endl;
		
		if(cntp > 0) {
			int l = 0, r = 200000, ans;
			while(l <= r) {
				int mid = (l + r) >> 1;
				if(judge(0, cntp, mid, f)) {
					ans = mid;
					r = mid - 1;
				}
				else {
					l = mid + 1; 
				}
			}
			tot += ans;
		}
		
		if(s[0] == 'M') tot ++;
		
		cout << tot << endl;
	}
}

我要按网上思路来le,,可恶 十一点了

0:17 按网上别人的代码流程来的,没啥意思说实话,不过这样写不容易出错,大体思路是一样的,

#include <bits/stdc++.h>
using namespace std;

int step;

bool judge(int pnum, int cnt, int znum) {
	int st = step;
	int php = 10, zhp = 50;
	
	while(cnt > 0 && znum > 0) {
		if(st > 0) {
			st --;
			zhp -= pnum;
			
		}
		else {
			php -= znum;
			zhp -= pnum;
				
		}
		
		
		if(php <= 0) {
			php = 10;
			pnum --; cnt --;
			st = 1;
		}
		if(zhp <= 0) {
			zhp = 50;
			znum --;
		}
		
	}
	
	if(cnt <= 0 && znum > 0) return 1;
	else return 0;
}

int getRes(int pnum, int cnt) {
	int l = 1, r = 200000, ans;
	while(l <= r) {
		int mid = (l + r) >> 1;
		if(judge(pnum, cnt, mid)) {
			ans = mid;
			r = mid - 1;
		}
		else {
			l = mid + 1;
		}
	}
	
	return ans;
}


int main() {
	int T;
	cin >> T;
	int cas = 0;
	while(T --) {
		++ cas;
		printf("Case %d: ", cas);
		
		string s;
		cin >> s;
		int n = s.size();
		
		int pnum = 0;
		int mnum = 0;
		for(int i = 0; i < n; ++ i) {
			if(s[i] == 'P') pnum ++;
			else mnum ++;
		}
		
		int ans = 0; 
		-- n;
		if(s[n] == 'M') {
			ans ++;
			-- n;
			step = 2;
		}
		else step = 1;
		
		while(n >= 0) {
			if(s[n] == 'M') {
				if(step > 1) {
					step --;
					if(pnum >= 50) ans ++;
					continue;
				}
				-- n;
				mnum --;
				ans ++;
				step = 2;
			} 
			else {
				
				int cnt =  0;
				for(int i = n; n >= 0; -- i) {
					if(s[i] == 'P') cnt ++;
					else break;
				}
				
				int res = getRes(pnum, cnt);
				//cout << pnum << " " << cnt << " " << res << endl;
				pnum -= cnt;
				ans += res;
				n -= cnt + 1;
				step = 2; 
			}
			
		}
		
		if(s[0] == 'M') ans ++;
		cout << ans << endl;
	} 
	
	return 0;
} 

C - Broken Watch

刚开始没有题面(),其实不是很难的,

小数据手模找一下规律分奇偶推出两个公式

有个对 2 64 2 ^ {64} 264的取模,unsigned long long 的自然溢出

然后有个除法,刚开始直接除然后wa了,后来考虑到有取模问题就需要用到逆元啥的,码了一个扩展欧几里得,但是发现 2 64 2^{64} 264其实取不到啊,ull 2 64 − 1 2 ^ {64} - 1 2641

于是只能在做的过程中先除掉,分类分死我了

#include <bits/stdc++.h>
using namespace std;

typedef unsigned long long ull;

//ull mod;
//
//ull exgcd(ull a, ull b, ull & x, ull & y) {
//	if(b == 0) {
//		x = 1, y = 0;
//		return a;
//	}
//	
//	ull d = exgcd(b, a % b, y, x);
//	
//	y -= (a / b) * x;
//	
//	return d;
//}

int main() {
	
	ull a, b, c, n;
	cin >> a >> b >> c >> n;
	
	int cnt = 1;
	
	if(a == b && a == c) {
		cnt = 3;
	}
	else if(a == b || a == c || b == c){
		cnt = 2;
	}
	
	ull ans;
	
	if(n <= 2) {
		cout << 0 ;
		return 0;
	}
	
	if(n & 1) {
		if(cnt == 1)
			ans = n * (1ull + (n / 2)) * (n / 2) ;
		else if(cnt == 2) {
			if(!((n / 2) & 1)) {
				ans = n * (1ull + (n / 2)) * (n / 4);
			}
			else {
				ans = n * ((1ull + (n / 2)) / 2) * (n / 2);
			}
		}
		else if (cnt == 3) {
			if(!((n / 2) & 1)) {
				if(n % 3 == 0)
					ans = (n / 3) * (1ull + (n / 2)) * (n / 4);
				else if((1ull + (n / 2)) % 3 == 0){
					ans = n * ((1ull + (n / 2)) / 3) * (n / 4);
				}
				else if((n / 4) % 3 == 0){
					ans = n * (1ull + (n / 2)) * (n / 12);
				}
			}
			else {
				//ans = n * ((1ull + (n / 2)) / 2) * (n / 2)
				if(n % 3 == 0)
					ans = (n / 3) * ((1ull + (n / 2)) / 2) * (n / 2);
				else if((1ull + (n / 2)) % 3 == 0){
					ans = n * ((1ull + (n / 2)) / 6) * (n / 2);
				}
				else if((n / 4) % 3 == 0){
					ans = n * ((1ull + (n / 2)) / 2) * (n / 6);
				}
			}
		}
	}
	else {
		if(cnt == 1)
			ans = n * ((2ull + (n / 2)) * (n / 2 - 1)+ (n - 2));
		else if(cnt == 2) {
			if(!(n & 1)) {
				ans = (n / 2) * ((2ull + (n / 2)) * (n / 2 - 1)+ (n - 2));
			}
			else {
				ans = n * (((2ull + (n / 2)) * (n / 2 - 1) + (n - 2)) / 2);
			}
		}
		else if(cnt == 3) {
			if(!(n & 1)) {
				if((n / 2) % 3 == 0)
					ans = (n / 6) * ((2ull + (n / 2)) * (n / 2 - 1)+ (n - 2));
				else
					ans = (n / 2) * (((2ull + (n / 2)) * (n / 2 - 1)+ (n - 2)) / 3);
			}
			else {
				if(n % 3 == 0)
					ans = (n / 3) * (((2ull + (n / 2)) * (n / 2 - 1) + (n - 2)) / 2);
				else
					ans = n * ((((2ull + (n / 2)) * (n / 2 - 1) + (n - 2)) / 2) / 3);
			}
		}
	}
	
	cout << ans;
	
	return 0;
}

D - A Simple Stone Game

思维,其实感觉不是大模拟

在为什么要分解质因数这里刚开始脑子de牢想了一会

还好

#include <bits/stdC++.h>
using namespace std;

typedef long long ll;

const int maxn = 1e5 + 10;
ll a[maxn];
vector<ll> nums;
int n;

ll getRes(ll x) {
	nums.clear();
	
	ll sum = 0;
	
	for(int i = 0; i < n; ++ i) {
		if(a[i] % x == 0) continue;
		ll num = a[i] % x;
		nums.push_back(num);
		sum += num;
	}
	
	sort(nums.begin(), nums.end());
	
	int siz = nums.size();
	ll res = 0;
	
	for(int i = siz - 1; i >= 0; -- i) {
		ll tmp = nums[i];
		res += x - tmp;
		sum -= x;
		if(sum <= 0) break;
	}
	
	return res;
}

int main() {
	int T;
	cin >> T;
	while(T --) {
		
		//int n;
		cin >> n;
		
		ll sum = 0;
		ll mx = 0;
		
		for(int i = 0; i < n; ++ i) {
			cin >> a[i];
			sum += a[i];
			mx = max(mx, a[i]);
		}
		
		ll ans = sum - mx;
		
		//cout << sum << " " << mx << endl;
		
		for(ll i = 2; i <= sum / i; ++ i) {			
			if(sum % i == 0) {
				//cout << "i :" << i << endl;
				ll res = getRes(i);
				//cout << "----" << i << " " << res << endl;
				ans = min(ans, res);
				while(sum % i == 0) sum /= i;
			}
			
		}
		if(sum > 1) {
			ll res = getRes(sum);
			//cout << "----" << sum << " " << res << endl;
			ans = min(ans, res); 
		}
		
		cout << ans << endl;
	}
	
	return 0;
}  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值