首页 > 其他分享 >绍大2022级ACM集训队新生选拔赛题解(更新中)

绍大2022级ACM集训队新生选拔赛题解(更新中)

时间:2022-10-24 15:24:36浏览次数:90  
标签:绍大 int 题解 Wei mn ACM 必胜 fg 必败

绍大2022级ACM集训队新生选拔赛题解(更新中)  

A.Honest

大致题意

在一个 n*n 的矩阵统计 “honest” 这个单词的个数。

基本思路

本题是签到题,只要用二维数组读入字符矩阵遍历统计即可。

代码

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

int main() {
	int n;
	bool fg=0;
	while(cin>>n) {
		if (n==0) break;
		if (fg) cout<<endl;
		fg=1;//输出换行
        
		char a[30][30];//字符数组
		
		for (int i=1; i<=n; i++) {
			for (int j=1; j<=n; j++) cin>>a[i][j];
		}

                int ans=0;
		for (int i=1; i<=n; i++) {
			for (int j=1; j<=n; j++) {
				string s="";
				string s1="";
                
				for (int k=0; k<6; k++) {
					if (j+k<=n) s=s+a[i][j+k]; //横向统计,超出矩阵范围不统计。
					if (i+k<=n) s1=s1+a[i+k][j]; //纵向统计。
				}

				if (s=="honest") ans++;
				if (s1=="honest") ans++;
				 
			}

		}
		
		cout<<ans;


	}
	return 0;
}

建议

尽早解决,避免罚时过高。

B.最短购物距离

大致题意

给定 n 个商店的坐标,选择一个商店作为起点,每次到达一个商店并放回,要求走完所有商店,求最少的总路程。

基本思路

由于 n 的数据范围非常小(只有\(100\)),所以只需要枚举每个商店作为起点,计算总路程并统计最短路程输出即可。

代码

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

int main() {
	int T;
	cin>>T;
    
	while(T--) {
		int a[200]={0};
		int n;
		cin>>n;
		for (int i=1;i<=n;i++){
			cin>>a[i];
		}
		sort(a+1,a+1+n);
        
		int ans=0x3f3f3f3f; // 开始假设最短路程为无穷大(超过题目最大路程的数即可视为无穷大)
		for (int i=1;i<=n;i++){
			int now=0;
			for (int j=1;j<=n;j++){//枚举商店
				now=now+abs(a[j]-a[i])*2;//计算路程之和,到达后目的地后要回到起点,所以要乘2
			}
			ans=min(ans,now);//取最短路程
		}
		
		cout<<ans<<endl;
		
	}
	return 0;
}

建议

题目数据范围过小时,可以选择用暴力枚举解决问题,以减少思考时间,降低罚时。

C.多少签多少钱

大致题意

有 n 种签子,给定每种签子的数量,价格和折扣,计算签子总数和总价格。

基本思路

直接求和即可,由于折扣会导致价格出现小数,所以要用 \(double\) 类型的变量表示价格。

代码

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

int main() {
	int T;
	bool fg=0;
	cin>>T;
	int cnt=0;
    
	while(T--) {
		if (fg) cout<<endl;
		fg=1;
		cnt++;//记录case
        
		int n;
		cin>>n;
        
		int ansn=0;//记录签子总数
		double ans=0;//记录总价格
        
		for (int i=1;i<=n;i++){
			int x;
			double y,z;
			cin>>x>>y>>z;
			
			ansn+=x;
			ans=ans+(x*y*(z/10));	
			
		}
		
		printf("Case #%d:%d %.1lf",cnt,ansn,ans);//价格保留1位小数
		
	}
	return 0;
}

建议

写程序前,应提前根据题目描述想好要用哪些类型的变量。

D.小学数学

大致题意

给定一个 n ,判断 n 的立方能否等于 n 个连续奇数之和,找到并输出这些连续奇数。

基本思路

这道题是一道找规律的题,从样例中不难看出, 1 的立方由 1 个奇数组成,2 的立方由俩个奇数组成,3 的立方由三个奇数组成,所以不难推出 n 的立方就是第 (1+2+...+n-1+1)个奇数后面连续的 n 个奇数之和。

当然,题目中还有 "-1" (即不存在)的情况1,事实上,当 n 为正数时都满足以上情况,只有 n<=0 时不存在。

代码

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

int main() {
	int T;
	bool fg=0;
	cin>>T;
    
	while(T--) {
		if (fg) cout<<endl;
		fg=1;
		ll n;
		cin>>n;
        
        if (n<=0) {
			cout<<"-1";
			continue;
		}//n<=0时不存在要求情况
        
		ll now=(n-1+1)*(n-1)/2; 
		now++;
		now=now*2-1; //计算连续奇数的第一个数
        
		for (int i=1;i<=n;i++){
            if (i!=1) cout<<" "; //末尾无空格
            cout<<now;
			now=now+2;
		}
		
	}
	return 0;
}

建议

遇到和数学有关的题,可以尝试一下能否从样例或者自己拟造的例子中找出规律。(事实上,很多类型的题都能够找规律,这种题不涉及算法,只考察思维)

E.游戏

大致题意

俩个人玩游戏,有一堆总数为 n 的柚子,双方轮流进行操作(俩人都采用最优策略),每次操作可以拿走 一个质数的幂次个数 的柚子(即 \(p^k\) \(p为质数\)), 最后拿走柚子的人获胜。给定一个 n ,询问先手操作的Wei能否获胜。

基本思路

这是一道博弈类型的题目,属于博弈题中最简单的一类。

对于此类追求胜负的博弈题,我们首先明确要一个概念,这个概念名为 必胜态

从字面上理解,必胜态就是必胜的状态,例如题中 n=1 或 n=2 时,Wei 都能直接把柚子取完,即 Wei 必胜,则我们称 n=1和 n=2 的状态为必胜态。

这样,其他不是必胜态的状态,就变成了必输的局面,称之为 必败态

以上的所有概念与结论,都有一个很重要的前提,即 俩人都采用最优策略 ,因为俩人都想方设法地赢,所以不会有哪一次操作出现失误,这样就不会出现 可能输或可能赢 的情况,即所有状态不是必胜就是必败。

在了解了博弈的基础知识后,回来看这道题,我们能发现:当 n=1-5 时,都为必胜态,6 为第一个必败态。

我们先把所有的质数和他们的幂筛选出来,因为这些数明显是必胜态。

筛选完之后,20 以内的数还剩下 : 6 10 12 14 15 18

由于 6 已经确定为必败态,所以当哪一个人开始操作时如果还剩 6 个柚子,他一定会输。

所以当 n=10 时,如果 Wei 拿走 4 个柚子,使柚子总数变成 6 ,那么就是 Peng 陷入了必败态,Wei 必胜,所以 10 也是必胜态。

当 n=12 时,Wei 只能拿走 2 个柚子,不然剩下的柚子都会被 Peng 一次性拿完,这样使 Peng 开始操作时还剩下 10 个柚子,此时 Peng 进入了必胜态,也就是 Wei 陷入了必败态,所以 12 也是 必败态。

接下来,由于 14,15 这俩个数Wei 都能使他们变成 12 ,即让 Peng 陷入必败态,所以 14 15 也是必胜态,而对于 n=18 的情况,不管 Wei 如何取, Peng 都能让他 变为 12 或者 6 ,即让 Wei 陷入必败态,所以 18 也是必败态。

至此,我们已经能猜到规律:只要 n 为 6 的倍数,Wei 就一定陷入必败态,反之皆为必胜态。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
	ll n;
	bool fg=0;
	while(cin>>n){
		if (fg) cout<<endl;
		fg=1;
		if (n%6==0) {
			cout<<"No";
		}else cout<<"Yes";
	}
	return 0;
}

建议

在学习完c++基础语法后,可以尝试学习一下各种算法,扩充自己的算法知识库,这样更有利于面对比赛时的各种情况。

F.包子

大致题意

给定一个范围 w 和一个整数 n 以及 n 个 整数,要求找出一共有多少个整数 k (\(0\leq k \leq w\)),使得 k 在加上这 n 个整数时始终保持(\(0\leq k \leq w\))。

基本思路

由于本题的 w 的数据范围为 (\(1 \leq w \leq 10^9\)),且有多组数据,所以不能采用暴力枚举的方法 (从 1 枚举到 w) 来求 k 的个数。

我们首先对每个整数 a[i] 求他的前缀和 (即\(\sum_{j = 1}^{i} a[j]\)) ,然后找出前缀和中的最大值和最小值。

如果前缀和的最大值或最小值的绝对值超过了 w ,则当 k 加到 最大值或最小值位置 时,一定会出现 k <0 或 k>w 的情况,则该 k 不满足要求。

之后的情况,我们用mx表示前缀和最大值,用mn表示最小值,分三种情况讨论:

1 : 当 \(mn\geq 0\) 时,若用 \((l,r)\) 表示 k 的答案区间,则 \(l\) 可以取到 0 ,而 \(r\) 不能超过 \(w-mx\) ,所以一共有 \(r-l+1\) 个 k 可取。

2:当 \(mx\leq0\) 时, \(r\) 可以取到 w ,但 \(l\) 不能小于 (|\(mn\)|) 所以 \(l=|mn|\) , 一共有 \(r-l+1\) 个 k 可取。

3:当 \(mx\geq 0\) 但 \(mn\leq0\) 时,\(l\) 不能小于 (|\(mn\)|) 而 \(r\) 不能超过 \(w-mx\) ,所以 \(l=|mn|\) , \(r=w-mx\) ,

一共有 \(r-l+1\) 个 k 可取。

至此,讨论结束。

代码

#include<bits/stdc++.h>
#include<map>
using namespace std;
typedef long long ll;
const int N=1005;
const ll INF=1e9+7;

int main() {
	bool fg=0;
	int n;
	ll w;
	while(cin>>n>>w) {
		if (fg) cout<<endl;
		fg=1;
        
		ll a[1005]={0};
		ll mx=-INF,mn=INF;//最大值和最小值
		ll pre=0;
        
		for (int i=1;i<=n;i++){
			ll x;
			cin>>x;
			pre=pre+x;
			mx=max(pre,mx);
			mn=min(mn,pre);
		}
		
		if (abs(mn)>w || abs(mx)>w) {
			cout<<"0";
		}else {
			ll l=0,r=w;
			if (mn<0) {
				if (mx<0) {
					l=abs(mn);
				}else {
					l=abs(mn);
					r=w-abs(mx);
				}
			}else {
				r=w-mx;
			}
			cout<<r-l+1;
		}
		
	}
	return 0;
}

建议

根据题目的数据范围,选择合适的做法。

标签:绍大,int,题解,Wei,mn,ACM,必胜,fg,必败
From: https://www.cnblogs.com/you-mu-jv-ruo/p/16821543.html

相关文章

  • Codeforces Round #829 (Div. 1/Div. 2) 1753 A B C D 题解
    Div1A/2C.MakeNonzeroSum令最后每个\(a_i\)的系数为\(c_i\)(\(c_i=1/-1\)),发现只要满足\(c_1=1\)(下标从1开始),且c中没有两个-1相连,就一定能找出一种划分方式。那我......
  • CF380C Sereja and Brackets 题解 数列分块
    题目链接:​​https://codeforces.com/contest/380/problem/C​​题目大意:给定长度为\(n(\le10^6)\)的一个括号序列,有\(m(\le10^5)\)次询问,每次询问给定一个区间\([l,......
  • SP685 SEQPAR - Partition the sequence 题解
    SP685SEQPAR-PartitionthesequenceSolution目录SP685SEQPAR-PartitionthesequenceSolution更好的阅读体验戳此进入题面SolutionCodeUPD更好的阅读体验戳此进......
  • ABC246Ex 01? Queries 题解
    ABC246Ex01?QueriesSolution目录ABC246Ex01?QueriesSolution更好的阅读体验戳此进入浅谈DDP与广义矩阵乘法(戳此进入)引入例题#1广义矩阵乘法DDP例题#0例题#0.5......
  • ABC246F typewriter 题解
    ABC246FtypewriterSolution目录ABC246FtypewriterSolution更好的阅读体验戳此进入题面SolutionCodeUPD更好的阅读体验戳此进入题面给定$n$个字符串,字符集为小......
  • ABC246D 2-variable Function 题解
    ABC246D2-variableFunctionSolution目录ABC246D2-variableFunctionSolution更好的阅读体验戳此进入题面SolutionCodeUPD更好的阅读体验戳此进入题面存在函数$f......
  • ABC246E Bishop 2 题解
    ABC246EBishop2Solution目录ABC246EBishop2Solution更好的阅读体验戳此进入题面SolutionCodeUPD更好的阅读体验戳此进入题面给定有障碍的网格图,.为空地,#为障碍......
  • LG-P5104 红包发红包 题解
    LG-P5104红包发红包Solution目录LG-P5104红包发红包Solution更好的阅读体验戳此进入UPD更好的阅读体验戳此进入(建议您从上方链接进入我的个人网站查看此Blog,在Luo......
  • ABC246C Coupon 题解
    ABC246CCouponSolution目录ABC246CCouponSolution更好的阅读体验戳此进入题面SolutionCodeUPD更好的阅读体验戳此进入题面$n$个物品第$i$个价格为$a_i$,......
  • The 18th Zhejiang Provincial Collegiate Programming Contest题解
    A.LeagueofLegends水题。点击查看代码#include<bits/stdc++.h>usingnamespacestd;#defineintlonglonginta[6];intb[6];signedmain(){for(......