济南 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  阅读(63)  评论(0)    收藏  举报