济南 CSP-J 刷题营 Day6 数学

Solution

T1 回文数

原题链接

4093: 回文数

简要思路

  • 进位情况
    当所有数位都为 \(9\) 的时候才会进位,此时输出形如 1000001 的形式
  • 不进位情况
  1. 如果 \(n\) 的前一半翻过来比后一半更大就直接把 \(n\) 的前一半翻过来贴在 \(n\) 的后面。
  2. 否则就把 \(n\) 的前一半 \(+1\) 翻过来贴在 \(n\) 的后面。

注意处理好 \(n\) 的位数为 奇数/偶数 的情况

完整代码

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

char s[201],ans[201];
int i;

signed main(){
	cin>>s;
	int len=strlen(s)-1;
	
	while(s[i++]=='9')
		if(i==len+1){
			s[0]='1';
			len++;
			for(;i>0;i--)
				s[i]='0';
		}	
	
	for(i=0;i<=len-i;i++)
		ans[i]=ans[len-i]=ans[i];
	
	if(strcmp(ans,s)<=0){
		while(ans[--i]=='9');ans[i]=ans[len-i]=++ans[i];
		for(i++;i<=len-i;i++)
			ans[i]=ans[len-i]='0';
	}
	
	cout<<ans<<endl;
	return 0;
}

T2 求和

原题链接

4094: 求和

简要思路

枚举所有 “好数”,最后去重即可。

注意当考虑数位中含有 23512457898 的情况时,注意分讨:数位前面有几个多加的数,后面又有几个。

完整代码

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

ll power10[15], n, ans = 0;//power10[i] 代表 10^i
const ll QQ = 2351257898;
vector<ll> vec;
int main() {
	
	power10[0] = 1;
	for (int i = 1; i < 15; i++) {//预处理
		power10[i] = power10[i - 1] * 10;
	}
	
	cin >> n;
	for (int i = 1; i <= n / QQ; i++) {//先把倍数的情况加入 vector 中
		vec.push_back(QQ * i);
	}
	
	//考虑当数位中有 2351257898 时的情况
	for (int pos = 1; pos <= 5; pos++) {//第一层代表枚举数位前面有几个多加的数,后面有几个多加的数
		for (int rest = 0; rest <= 9999; rest++) {//第二层枚举代表多加的数是啥
			ll tmp = QQ * power10[pos - 1] + rest % power10[pos - 1] + rest / power10[pos - 1] * power10[pos + 9];//计算
			if (tmp <= n)
				vec.push_back(tmp);//如果合法才计入答案
		}
	}
	sort(vec.begin(), vec.end());//排序
	vec.erase(unique(vec.begin(), vec.end()), vec.end());//去重
	for (auto x: vec) {//枚举 vector 中的每一个数
		ans += x;
	}
	
	
	cout << ans << endl;
	
	return 0;
}

T3 计算

原题链接

4095: 计算

简要思路

前缀和 + 桶 + 差分。

完整代码

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

int a[maxn], cnt[maxn], n, l, r;
ll ans[maxn], tag[maxn];
int main() {
	cin >> n >> l >> r;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for (int i = 1; i <= n; i++) {
		ans[0] += l / a[i];
	}
	
	for (int i = 1; i <= n; i++) {
		if (a[i] < maxn)
			cnt[a[i]]++;
	}
	for (int i = 1; i < maxn; i++) {
		int pos = (l / i + 1) * i;
		while (pos <= r) {
			tag[pos - l] += cnt[i];
			pos += i;
		}
	}
	for (int i = 1; i <= n; i++) {
		if (a[i] < maxn)
			continue;

		int pos = (l / a[i] + 1) * a[i];
		while (pos <= r) {
			tag[pos - l]++;
			pos += a[i];
		}
	}
	
	for (int i = 1; i <= r - l; i++) {
		ans[i] = ans[i - 1] + tag[i];
	}
	
	for (int i = 0; i <= r - l; i++) {
		cout << ans[i] << "\n "[i < r - l];
	}
	return 0;
}

T4 保 KDA

原题链接

4096: 保 KDA

简要思路

01 分数规划 + 背包

完整代码

咕咕。

讲课笔记

洛谷 P3908

原题链接

P3908 数列之异或

相关知识

位运算

位运算符号:&,|,^

  • &
    1&1=1 1&0=0 0&0=0 0&1=0

  • |
    1|1=1 1|0=1 0|1=1 0|0=0

  • ^
    二进制的不进位加法。
    1^1=0 1^0=1 0^1=1 0^0=0
    两个相同的数字异或答案为 \(0\)\(a^a=0\)

简要思路

一个偶数异或下一个奇数的答案为 \(1\)\((2k) \oplus (2k+1) = 1\)

  1. \(n\) 是奇数时
    如果 \((n-1)/2\) 为奇数,答案为 \(0\)
    偶数答案则为 \(1\)
  2. \(n\) 为偶数时,先计算 \(n-1\) 的答案,再异或上 \(n\)

完整代码

#include<bits/stdc++.h>
using namespace std;
long long n;
signed main(){
	cin>>n;
	long long ans=0;
	if(n%2==1){
		if(((n+1)/2)%2==1)ans^=1;
		cout<<ans<<endl;
	}
	else{
		n++;
		ans=n;
		if(((n+1)/2)%2==1)ans^=1;
		cout<<ans<<endl;
	}
	return 0;
}

洛谷 P4942

原题链接

题面

相关知识

如果一个数的数位之和为 \(3\) 的倍数,那么这个数就是 \(3\) 的倍数。
如果一个数的个数位上为 \(0\)\(5\),那么这个数就是 \(5\) 的倍数。
如果一个数的千位及其以前的数位组成的数减去后三位数,得到的答案的绝对值为 \(7\)\(11\)\(13\) 的倍数,那么这个数就是 \(7\)\(11\)\(13\) 的倍数。

简要思路

完整代码

洛谷 P6267

原题链接

题面

相关知识

分解质因数

简要思路

完整代码

洛谷 P1029

原题链接

题面

相关知识

最大公约数和最小公倍数

  • 辗转相除
  • 指数(分解质因子),min-max

简要思路

完整代码

洛谷 P1072

原题链接

题面

相关知识

简要思路

  • 模拟

  • PPT

完整代码

  • 模拟做法

  • (PPT) 做法

洛谷 P3197

原题链接

题面

相关知识

组合数

  • 例题 1
    共有 \(n\) 个相同的小球,放置于 \(m\) 个不同个盒子中,保证每个盒子都非空的方案数。

\(C^{m-1}_{n-1}\)

  • 例题 2
    如果不要求非空,一开始就将每个盒子的初始值为 \(1\),最后减去 \(m\) 个小球就为 \(C^{m-1}_{n+m-1}\)

上述为 插板法。

  • 例题 3
    不同小球,不同盒子,可以为空。

每个小球都可以放置在任何盒子里,答案为 \(m^n\)

简要思路

完整代码

进阶

一号房间和 \(n\) 号房间连接,成为了环。

今日题单

题单

题目 是否通过
P3908 数列之异或 \(\color{yellowgreen}{√}\)
P4942 小凯的数字 \(\color{yellowgreen}{√}\)
P6267 [SHOI2002] N的连续数拆分 \(\color{yellowgreen}{√}\)
P1029 [NOIP2001 普及组] 最大公约数和最小公倍数问题 \(\color{yellowgreen}{√}\)
P1072 [NOIP2009 提高组] Hankson 的趣味题 \(\{yellowgreen}{√}\)
posted @ 2023-07-29 19:04  CheZiHe929  阅读(16)  评论(0编辑  收藏  举报