Codeforces Round 937 (Div.4)

本文分享了解析CodeforcesRound937中的五道编程题,包括判断数列性质、图案填充、时钟转换、二进制验证和最短重复子串问题,展示了作者的解题思路和技术应用。

codeforces Round.937 div4 (第一次打只写出4题QAQ 慢慢补题)

A题

语法题,判断三个数是递增还是先增后减再则NONE

#include <iostream>
using namespace std;
void solve() {
	int a, b, c;
	cin >> a >> b >> c;
	if(a < b && b < c) cout << "STAIR"<< "\n";
	else if(a < b && b > c) cout << "PEAK"<< "\n";
	else cout << "NONE" << "\n";
}

int main() {
	int T;
cin >> T;
	while(T--) 
	    solve();
}

B题

技巧题 打印 相邻#.交错 隔行交错 并且放大一倍
扩大了两倍
宏观地将2*2看成1

我的写法 (我直接模拟填表了 填2*2 然后先填# 再填. 然后 统计一下上一行填了奇数个#还是偶数个 现在都不太好看了这个代码 反正就是flag控制第下一个填#还是填.)

#include <iostream>
using namespace std;
const int N = 100;

int main(void) {
	int T;
	cin >> T;
	while (T--) {

		int n;
		cin >> n;
		int a[N][N];

		int flag = 1;
		for (int i = 1; i <= 2 * n; i += 2) {
			int cnt = 0;
			for (int j = 1; j <= 2 * n; j += 2) {
				if (flag)

				{
					a[i][j] = 1;
					a[i + 1][j] = 1;
					a[i][j + 1] = 1;
					a[i + 1][j + 1] = 1;
				}

				flag = !flag;//下一个填和上一个不一样的符号
				cnt++;//这个cnt其实记的是填了多少块(2*2)


			}
			if (!(cnt & 1))
				flag = !flag;//换行了 如果上一行填了偶数块 flag取反偶数次 1还是1 下一行要填. 所以还要取反一次



		}



		for (int i = 1; i <= 2 * n; i++) {
			for (int j = 1; j <= 2 * n; j++) {
				if (a[i][j] == 1)
					cout << '#';
				else
					cout << '.';


			}

			cout << endl;
		}
	}
	return 0;

}

C题

时钟12小时制转换 注意00点和12点 还有时钟<12都是am 否则pm

#include <iostream>
using namespace std;

void solve() {
    int h, m; 
	char c;
    cin >> h >> c >> m;
    string am = (h < 12 ? " AM" : " PM");
    h = (h % 12 ? h % 12 : 12);
    cout << (h < 10 ? "0" : "") << h << c << (m < 10 ? "0" : "") << m << am << '\n';
}

int main() {

	int T;
	 cin >> T;
	  while(T--) 
	  solve();
}

D题

二进制十进制数(一个十进制的数 每一位都是0或者1)
打表处理2位到5位 二进制十进制数
首先特判一个数每一位是否已经满足二进制十进制数的特点
用表作为因子试将这个数约尽
约的尽就是二进制十进制数 约不尽就不是

    #include <iostream>
    #include <cstring>
    using namespace std;
    const int N = 1010;
     
    int a[N], cnt;
     
    void init() {
     
    	for (int i = 2; i <= 63; i++) {
    		int x = i;
    		int s = 0, t = 1;
    		while (x) {
    			s +=  (x & 1) * t;
    			t *= 10;
    			x >>= 1;
    		}
    		a[cnt++] = s;
    	}
    //
    //	for (int i = 0; i < cnt; i++)
    //		cout << a[i] << ' ';
     
    }
     
    bool isb(int x) {
    	while (x) {
    		if (x % 10 > 1)
    			return false;
    		x /= 10;
    	}
    	return true;
    }
     
    void solve() {
    	int x;
    	cin >> x;
    	if (isb(x)) {
    		puts("YES");
    		return;
    	}
    	for (int i = 0; i < cnt; i++) {
    		while (x % a[i] == 0) {
    			x /= a[i];
    		}
    	}
    	if (x > 1) {
    		puts("NO");
     
    	} else
    		puts("YES");
     
    }
     
    int main(void) {
    	init();
    	int T;
    	cin >> T;
    	while (T--) {
    		solve();
     
    	}
     
    	return 0;
     
    }

E题

找最短近似重复子串
就是找一个子串用这个子串重复叠加构造一个和原串的长度一样的字符串 和原串对比,最多只会有一个地方不同
这个子串长度是n的约数 最坏是n(一定可以)
然后我想截子串的
枚举长度
在这里插入图片描述
假设n个子串最多只有1个串是错误的 选两个出来其中一个必定是对的 如果一个不对 假设不成立 那就有超过1个串是错误的 那只能扩展子串的长度

#include <iostream>
using namespace std;
int n;
string s;


bool check(int len) {
	int n = s.size();

	string s1 = s.substr(0, len);
	string s2 = s.substr(n - len);


	string a, b;

	for (int i = 0; i < n / len; i++)
		a += s1, b += s2;

	int cnt1 = 0, cnt2 = 0;
	//统计两个的不匹配位置的数量
	for (int i = 0; i < n; i++) {
		int j = i;
		if (s[i] != a[j])
			cnt1++;
		if (s[i] != b[j])
			cnt2++;

	}
	if (min(cnt1, cnt2) <= 1)//有一个满足
		return true;
	return false;

}

void solve() {

	cin >> n;
	cin >> s;
	for (int i = 1; i <= n; i++) {
		if (n % i) { //不能整除i
			continue;
		}

		else if (check(i)) {
			cout << i << endl;
			break;
		}

	}
}

int main(void) {
	int T;
	cin >> T;
	while (T--) {
		solve();

	}



	return 0;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值