郑州轻工业大学 23级新生C语言周赛(5)

ZZULIOJ

分析和思路以及代码 持续更新中

问题 A: 简单的小游戏1

分析:

模拟,如果之前就存在2048这个数的话 就直接输出yes,没有的话就去枚举2的次方,看看这个数有没有,有的话,个数是不是大于2的,要是大于2了 我就去合成 合成的个数就给当前这个数*2

代码:

#include<bits/stdc++.h>
#define _for(i, a, b) for(int i = a; i <= b; ++ i ) 
using namespace std;

const int N = 2e5 + 10;
int a[N];
int n, m;
string s;

signed main() {
	int t;
	cin >> t;
	while(t--) {
		cin >> n;
		map<int, int>mp;
		mp[2048] = 0;
		
		bool flag = false;
		_for(i, 1, n) {
			cin >> a[i];
			if(a[i] == 2048) {
				flag = true;
			}
			mp[a[i]]++;
		}
		if(flag) {
			cout << "yes" << endl;
		} else {
				for(int i = 0; i <= 10; ++ i ) {
					int tt = pow(2, i);
					if(mp[tt] >= 2) {
						int gs = mp[tt] / 2;
						mp[tt] %= 2;
						mp[2 * tt] += gs;
					}
			}
			if(mp[2048]) {
				cout << "yes" << endl;
			} else {
				cout << "no" << endl;
			}
		} 
		
	}
	return 0;
}

问题 B: 简单的小游戏2

分析:

也是一个枚举的题,但是需要注意的是k太大了,我们注意到,l和r并不大,因此是会出现循环的,几次一循环呢?(r - l + 1) 因此我们可以拿k进行取余一下,减少时间

代码:

#include<bits/stdc++.h>

#define _for(i, a, b) for(int i = a; i <= b; ++i)
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;

const int N = 2e5 + 10;
int a[N];
int n, m;
string s;

void move(int l, int r) {
	char p = s[r];
	for(int i = r; i >= l; -- i ) {
		s[i] = s[i - 1];
	}
	s[l] = p;
}
signed main() {
	IOS;
	cin >> s;
	int q;
	cin >> q;
	while(q--) {
		int l, r, k;
		cin >> l >> r >> k;
		//必须要去优化k去进行取余
		l--, r--;
		int t = (r - l + 1);
		k %= t;
		while(k--) {
		     move(l, r);
		}
	} 
	cout << s << endl;
	return 0;
}

问题 C: 购物的小a

分析:

这个题气死我了,是小学的知识吗? 刚开始的理解就出了问题. 举个例子,比如 这个数是大于1000的,那么100到300这个区间就会去便宜(300-100)*0.9 而不是(x-100)*0.9 其他同理,还要加个特判,要是这个代金券m是大于n的,我就直接输出0了,不用再去打折什么的了,其他的情况是 这代金券是用还是不用呢? 要是用的话,必须在打折之前用 也就是代码里面的 youhui(n - m),要是不用的话 就直接youhui(n),取最小的即可

代码:

#include<bits/stdc++.h>
#define y1 Y1
#define fi first
#define endl "\n"
#define se second
#define PI acos(-1)
#define int long long
#define pb(x) push_back(x)
#define PII pair<int, int>
#define Yes cout << "Yes\n";
#define No cout << "No\n";
#define YES cout << "YES\n";
#define NO cout << "NO\n";
#define _for(i, a, b) for(int i = a; i <= b; ++i)
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;

const int N = 2e5 + 10;
int a[N];
double n, m;
string s;

int youhui(double x) {
	double t = 0;
	int p = x;
	if(x <= 100) {
		return x;
	} else if(x <= 300) {//100 - 300
		t += 100 + (x - 100) * 0.9;
	} else if(x <= 500) {
		t += 100 + (300- 100) * 0.9 + (x - 300) * 0.85;
	} else if(x <= 800) {
		t += 100 + (300 - 100) * 0.9 + (500 - 300) * 0.85 + (x - 500) * 0.8;
 	} else if(x <= 1000) {
		t += 100 + (300 - 100) * 0.9 + (500 - 300) * 0.85 + (800 - 500) * 0.8 + (x - 800) * 0.75;
	} else if(x > 1000){
		t += 100 + (300 - 100) * 0.9 + (500 - 300) * 0.85 + (800 - 500) * 0.8 + (1000 - 800) * 0.75 + (x - 1000) * 0.7;
	}
	return (int)t;
}

signed main() {
	//代金券只能在   打折之前   使用
	int ret = 1e20;
	cin >> n >> m;
	if(m >= n) {//ret保证是非负的 
		cout << 0 << endl;
		return 0;
	}
	//代金券 用还是不用
	//1 不用
	ret = min(ret, youhui(n));
	//用
	ret = min(ret, youhui(n - m));
	cout << ret << endl;
	return 0;
}

问题 D: 有趣的信息

分析:

读题是真的重要啊, 比赛的时候读错题了 无语 今天补题的时候 又读了一遍题 才发现还是蛮简单的, 但是有一个细节需要注意到,就是 在没操作之前 还需要统计一下他的'x'这个数量是不是大于k的 要是大于k的话 还要++

代码: 

#include<bits/stdc++.h>
#define y1 Y1
#define fi first
#define endl "\n"
#define PI acos(-1)
#define int long long
#define pb(x) push_back(x)
#define PII pair<int, int>
#define Yes cout << "Yes\n";
#define No cout << "No\n";
#define YES cout << "YES\n";
#define NO cout << "NO\n";
#define _for(i, a, b) for(int i = a; i <= b; ++i)
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;

const int N = 2e5 + 10;
int a[N];
int n, k, t;
string s;
unordered_map<char, int>mp;//每个字符 在s里面出现的次数 

char zh(char x) {
	if(x == 'Z')return 'A';
	if(x == 'z')return 'a';
	return (char)(x + 1);
}

signed main() {
	IOS;
	cin >> s >> n >> k;
    bool flag = false;
	_for(i, 0, s.size() - 1) {
		mp[s[i]]++;
	} 
	if(mp['x'] > k)t++;
	//在   操作过程中 
	//如果 xxx 出现的次数等于或大于 3 次,输出 "xxx * 3" ; 
	//如果 xxx 出现 1 次,输出 "xxx" ; 
	//其余情况输出 "None"
	
	while(n--) {
		int l, r;
		cin >> l >> r;
		l--,r--; 
		for(int i = l; i <= r; ++ i ) {
			char prev = s[i];//没转换之前的
			mp[prev]--;
			s[i] = zh(prev);//转换之后的 
			mp[s[i]]++;
			if(mp['x'] > k) {
				t++;
			}
			if(t >= 3) {
				cout << "xxx * 3" << endl;
				return 0;
			}
		} 
    }    
    if(t == 1) {
    	cout << "xxx" << endl;
    	return 0;
	}
	cout << "None" << endl;
	return 0; 
}

问题 E: 喜欢刷b站的学长

分析:

模拟, 也就是给你 两个日期,让你去判断 第一个日期是不是比第二个日期大的, 这个先去判断年份,然后年份有结果了就不用去比较其他的了,要是年份相同的话,就去比较月份 同理依次下去

代码:

#include<bits/stdc++.h>
#define _for(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;

const int N = 2e5 + 10;
int a[N];
int n, m;

signed main() {
	//注意 是 这一天 
	int h1, m1, s1;
	cin >> h1 >> m1 >> s1;
	int h2, m2, s2;
	cin >> h2 >> m2 >> s2;
	if(h2 > h1 || (h2 == h1 && m2 > m1) || (h2 == h1 && m2 == m1 && s2 > s2)) {
		cout << "YES" << endl;
	} else {
		cout << "NO" << endl;
	}
	return 0;
}

问题 F: 不会Dynamic Programming怎么办

分析: 

方法一:

这个题是有规律的,当然也是可以去暴力的 直接去从a到b去枚举 看看他是<10的话 就是一个数 就加一,要是<100的话就是两位数,要是<1000就是3位数, 不要用while去判断他的位数,是会TLE的

方法二:

举个例子让你求9到100之间的, 我的思路是先求9他这个位数是1为 然后最大的1位数是9 9到9之间有一个数也就是(9 - 9 + 1) * 1(这个1是位数) 然后100是3位的 说明他们之间是存在两位数的 全部的两位数 先看看最小的两位数是10 最大的两位数是99 他们之间的数的个数是(99 - 10 + 1) * 2(位数),乘2的原因是 10到99一共有99-10+1个 每个数贡献两位 

代码:

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

const int N = 2e5 + 10;
int a[N];
int n, m;
string s;

int ws(int x) {//判断这个数 有几位数 
	int t = 0;
	while(x) {
		x /= 10;
		t++;
	}
	return t;
}

int ma(int w) {//这个位最大的数 
	return pow(10, w) - 1;
}

int mi(int w) {//这个位最小的数 
	return pow(10, w - 1);
}
signed main() {
	int l, r, t, tt = 0;
	cin >> l >> r >> t;
	
	int ws1 = ws(l);
	int ws2 = ws(r);
	if(ws1 == ws2) {
		tt = (r - l + 1) * ws1;
	} else {
		tt += (ma(ws1) - l + 1) * ws1;
		for(int i = ws1 + 1; i <= ws2 - 1; ++ i ) {
			tt += (ma(i) - mi(i) + 1) * i;
			if(tt > t) {
				cout << "nizhenlihai!" << endl;
				return 0;
			}
		}
		tt += (r - mi(ws2) + 1) * ws2;
	}
	if(tt == t) {
		cout << "nizhenlihai!" << endl;
	} else {
		cout << "laji" << endl;
	}
	return 0;
}

问题 G: 小F和小G

分析:

G题重测被挂掉了 , 有点难啊

要快速获取里面的有用信息, 大致的意思就是给你两个字符串s1, s2, 你去交换s1串里面的字符,然后尽量让s1和s2一样, 问最后最少有多少个实在对不上的 用两个数组 一个去统计s1的 一个去统计s2里面的字符, 然后看看他们对应的字符的差距 记得答案要除以2 ,因为s1里面和s2里面都会去贡献不同的字符

代码:

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

const int N = 2e5 + 10;
int n, m;
string s;
int a[27], b[27];

signed main() {
	cin >> n;
	string s1;
	cin >> s1;
	string s2;
	cin >> s2;
	for(int i = 0; i < n; ++ i ) {
		a[s1[i] - 'a']++;
		b[s2[i] - 'a']++;
	}
	int ret = 0;
	for(int i = 0; i < 26; ++ i ) {
		ret += abs(a[i] - b[i]);
	}
	cout << ret / 2 << endl;
	return 0;
}

问题 H: X学长

分析:

这个题 就凸显出了 c++里面的substr了,可以看看我之间对他的简介哈, 这个是截取字符串的,第一个参数是起始位置,第二个是你要截取的个数,也是简单题,我用的是map去存每个字符串的里面的出生年的信息

s2.substr(6, 4)

然后看看他的个数是不是为1 要是为1的话 就说明没人和他同一年 然后就输出 年龄最大的 ,要是有和他出生年份是一样的话 就输出一样的个数 也就是mp[s2.substr(6, 4)]

怎么去求年龄最大的呢? 注意年龄大 说明他的 年 月 日份小 1998是比1999年出生的早的

代码:

#include<bits/stdc++.h>
#define endl "\n"
#define se second
#define PI acos(-1)
#define int long long
#define pb(x) push_back(x)
#define PII pair<int, int>
#define Yes cout << "Yes\n";
#define No cout << "No\n";
#define YES cout << "YES\n";
#define NO cout << "NO\n";
#define _for(i, a, b) for(int i = a; i <= b; ++i)
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;

const int N = 2e5 + 10;
int a[N];
int n;
string s;
int ret = 0;
map<string, int>mp;
pair<string, string>p[110];

int y = 99999, m = 999, d = 999;

int zh(string t) {
	int p = 0;
	for(int i = 0; i < t.size(); ++ i ) {
		p = p * 10 + (t[i] - '0');
	}
	return p;
}

signed main() {
	IOS;
	cin >> n;
	_for(i, 1, n) {
		string s1, s2;
		cin >> s1 >> s2;
		mp[s2.substr(6, 4)]++;
		ret = max(ret, mp[s2.substr(6, 4)]);
		p[i] = {s1, s2};
	}
	if(ret == 1) {
		int jl = 1;
		_for(i, 1, n) {
			s = p[i].se;
			int yy = zh(s.substr(6, 4));
			int mm = zh(s.substr(10, 2));
			int dd = zh(s.substr(12, 2));
			bool flag = false;
			if(yy < y) {
				flag = true;
			}  
			 if(yy == y && mm < m) {
				flag = true;
			} 
			 if(yy == y && mm == m && d < dd) {
				flag = true;
			}
			if(flag) {
				y = yy;
				m = mm;
				d = dd;
				jl = i;
			}
		}
		cout << p[jl].fi << " " << p[jl].se << endl;
	} else {
		cout << ret << endl;
	}
	return 0;
}

问题 I: 你与女神共进晚餐

分析:

提取信息依然是很重要的, 这个题就是让你求每行的最小值 然后 这些最小值里面的最大值 就ok了

代码:

#include<bits/stdc++.h>
#define y1 Y1
#define fi first
#define endl "\n"
#define se second
#define PI acos(-1)
#define int long long
#define pb(x) push_back(x)
#define PII pair<int, int>
#define Yes cout << "Yes\n";
#define No cout << "No\n";
#define YES cout << "YES\n";
#define NO cout << "NO\n";
#define _for(i, a, b) for(int i = a; i <= b; ++i)
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;

const int N = 2e5 + 10;
int a[1010][1010];
int n, m;
string s;

signed main() {
	IOS;
	int ret = 0;
	cin >> n >> m;
	_for(i, 1, n) {
		int t = 0x3f3f3f3f;
		_for(j, 1, m) {
			cin >> a[i][j];
			t = min(a[i][j], t);
		}
		ret = max(ret, t);
	}
	cout << ret << endl;
	return 0;
}

问题 J: 公交车上的座

分析:

也是模拟,自己可以去模拟一下 先后顺序 注意一下就可以了

代码:

#include<bits/stdc++.h>
#define y1 Y1
#define fi first
#define endl "\n"
#define se second
#define PI acos(-1)
#define int long long
#define pb(x) push_back(x)
#define PII pair<int, int>
#define Yes cout << "Yes\n";
#define No cout << "No\n";
#define YES cout << "YES\n";
#define NO cout << "NO\n";
#define _for(i, a, b) for(int i = a; i <= b; ++i)
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;

const int N = 2e5 + 10;
int n, m;
string s;
int a[1010][5];
vector<int>v(10010);

signed main() {
	IOS;
	cin >> n >> m;
	
	//先排吧
	bool flag = false;
	int t = 1;
	for(int i = 1; i <= n; ++ i ) {
		a[i][1] = t++;
		m--;
		if(m == 0)break;
		a[i][4] = t++;
		m--;
		if(m == 0)break;
	}
	if(m) {
		for(int i = 1; i <= n; ++ i ) {
			a[i][2] = t++;
			m--;
			if(m == 0)break;
			a[i][3] = t++;
			m--;
			if(m == 0)break;
		}
	}
	for(int i = 1; i <= n; ++ i ) {
		if(a[i][2] != 0)
		 cout << a[i][2] << ' ';
		
		if(a[i][1] != 0)
		 cout << a[i][1] << ' ';
		
		if(a[i][3] != 0)
		 cout << a[i][3] << ' ';
		
		if(a[i][4] != 0)
		 cout << a[i][4] << ' ';
	}

	return 0;
}
  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FindYou.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值