2021 寒假集训 Day4

7-1 质因数分解

题目描述:输出一个数的质因数分解结果,类似于 6618848 = 2 5 ∗ 17 ∗ 2 3 3 6618848 = 2^5 * 17 * 23^3 6618848=2517233的形式。

题解:

因 为 此 题 数 据 范 围 为 i n t 范 围 , 而 直 接 找 质 因 子 也 几 乎 是 θ ( n ) 的 , 所 以 我 们 模 拟 题 目 要 求 即 可 , 找 到 一 个 质 因 子 直 接 把 他 全 部 除 尽 。 因为此题数据范围为int范围,而直接找质因子也几乎是\theta(n)的,所以我们模拟题目要求即可,找到一个质因子直接把他全部除尽。 intθ(n)

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n=0;
	bool flag=false;
	string a;
	cin>>a;
	for(int i=0;i<a.size();i++){
		n=n*10;
		n=n+a[i]-'0';
	}
	printf("%d =",n);
	for(int i=2;i<=n;i++){
		if(n%i==0){
			int sum=0;
			while(n%i==0){
				sum++;
				n=n/i;
			}
			if(flag) printf(" *");
			else if(!flag) flag=true;
			if(sum!=1) printf(" %d^%d",i,sum);
			else printf(" %d",i);
		}
	}
	return 0;
}

7-2 毒酒几何

题目描述:

有 若 干 只 老 鼠 , 来 喝 若 干 瓶 酒 , 编 号 为 i 的 老 鼠 喝 的 酒 的 编 号 为 所 有 二 进 制 i 位 为 1 的 编 号 的 酒 , 给 出 死 亡 的 老 鼠 的 编 号 , 请 找 出 有 毒 的 酒 。 有若干只老鼠,来喝若干瓶酒,编号为i的老鼠喝的酒的编号为所有二进制i位为1的编号的酒,给出死亡的老鼠的编号,请找出有毒的酒。 ii1

题解:题目意思转化到这一步已经比较明了了,用2的i-1次幂来表示当前第i位为1。

#include<bits/stdc++.h>
using namespace std;
bool book[1005];
int ans;
bool flag;
int main(){
    int t;
    while(scanf("%d,",&t)==1){
        flag=true;
        if(!book[t]){
            ans+=pow(2,t-1);
            book[t]=true;
        }
    }
    if(flag) printf("%d",ans);
    else puts("0");
    return 0;
}

7-3 手指游戏

题目描述:

输 入 五 个 手 指 的 英 文 , 判 断 哪 一 方 赢 或 输 , 大 拇 指 大 于 食 指 大 于 中 指 大 于 无 名 指 大 于 小 拇 指 , 小 拇 指 大 于 大 拇 指 , 其 余 的 情 况 无 法 比 较 ( 如 大 拇 指 和 中 指 ) 输入五个手指的英文,判断哪一方赢或输,大拇指大于食指大于中指大于无名指大于小拇指,小拇指大于大拇指,其余的情况无法比较(如大拇指和中指)

题解:

按 照 题 目 意 思 模 拟 , 掌 握 字 符 串 模 拟 基 本 规 律 即 可 。 按照题目意思模拟,掌握字符串模拟基本规律即可。

#include<bits/stdc++.h>
//代码全WA了,但是思路基本就这样,欢迎Debug
using namespace std;
int main(){
	int n;
	scanf("%d\n",&n);
	while(n--){
		int mp1,mp2;
		string f,d;
		char ch;
		while(ch=getchar()){
			if(ch==',') break;
			if(ch==' ') continue;
			f.push_back(ch);
		}
		while(ch=getchar()){
			if(ch=='\n') break;
			if(ch==' ') continue;
			d.push_back(ch);
		}
		if(f[0]=='t' && f.size()==5) mp1=1;
		else if(f[0]=='f') mp1=2;
		else if(f[0]=='m') mp1=3;
		else if(f[0]=='t' && f.size()==11) mp1=4;
		else if(f[0]=='l') mp1=5;
		if(d[0]=='t' && d.size()==5) mp2=1;
		else if(d[0]=='f') mp2=2;
		else if(d[0]=='m') mp2=3;
		else if(d[0]=='t' && d.size()==11) mp2=4;
		else if(d[0]=='l') mp2=5;
		if(mp1==mp2-1) puts("Win");
		else if(mp1==mp2+1) puts("Lose");
		else if(mp1==5 && mp2==1) puts("Lose");
		else if(mp1==1 && mp2==5) puts("Win");
		else puts("Draw");
	}
	return 0;
}

7-4 正弦函数

题目描述:

根 据 麦 克 劳 林 公 式 计 算 任 意 角 的 正 弦 。 根据麦克劳林公式计算任意角的正弦。

题解:

带 小 数 的 计 算 和 数 学 题 都 要 特 别 小 心 精 度 的 问 题 , 最 好 用 差 值 小 于 精 度 的 方 式 判 断 相 等 。 带小数的计算和数学题都要特别小心精度的问题,最好用差值小于精度的方式判断相等。

#include<bits/stdc++.h>
using namespace std;
//WA了两个点T了一个点,7分,欢迎Debug
double mike(int h,double x){
	double ans=1;
	if(h%2==1){
		for(int i=1;i<=2*h-1;i++){
			ans*=(x/i);
		}
	}
	if(h%2==0){
		for(int i=1;i<=2*h-1;i++){
			ans*=(x/i);
		}
		ans=-ans;
	}
	return ans;
}
int main(){
	double x,y;
	while(x>=2*acos(-1)){
		x-=acos(-1);
	}
	const double eps=1e-6;
	double ans=0;
	cin>>x>>y;
	for(int i=1;;i++){
		if(mike(i,x)<eps&&-mike(i,x)<y+eps){
			ans+=mike(i,x);
			break;
		}
			if(mike(i,x)>eps&&mike(i,x)<y+eps){
			ans+=mike(i,x);
			break;
		}
		ans+=mike(i,x);
	}
	printf("%.6f",ans);
	return 0;
}

7-5 检查密码

题目描述:

给 出 一 串 字 符 串 要 求 只 能 由 字 母 数 字 和 小 数 点 “ . ” 组 成 , 还 必 须 都 有 数 字 和 字 母 。 且 长 度 不 能 小 于 6 。 给出一串字符串要求只能由字母数字和小数点“.”组成,还必须都有数字和字母。且长度不能小于6。 .6

题解:

按 照 题 目 意 思 模 拟 即 可 , 可 以 用 到 比 较 快 捷 的 i s d i g i t ( ) 和 i s a l p h a ( ) 函 数 来 快 速 判 断 当 前 字 符 时 候 是 数 字 字 符 和 字 母 字 符 。 按照题目意思模拟即可,可以用到比较快捷的isdigit()和isalpha()函数来快速判断当前字符时候是数字字符和字母字符。 isdigit()isalpha()

#include<stdio.h>
 
int main(void)
{
    int i,n,f1,f2,f3; //f1标记数字,f2标记字母,f3标记其他字符
    char c;
    scanf("%d%*c",&n);
    for (;n>0;n--)
    {
        i=0;f1=0;f2=0;f3=0;
        do
        {
            scanf("%c",&c);i++;
            if (c>='0' && c<='9') f1=1;
            else if ((c>='a' && c<='z') || (c>='A' && c<='Z')) f2=1;
            else if (!(c=='.'|| c=='\n')) f3=1;
        }while(c!='\n');
        if (i-1<6) printf("Your password is tai duan le.\n");
        else if (f3==1) printf("Your password is tai luan le.\n");
        else if (f1==0) printf("Your password needs shu zi.\n");
        else if (f2==0) printf("Your password needs zi mu.\n");
        else printf("Your password is wan mei.\n");
    }
    return 0;
}

7-6 魔方阵

题目描述:

输 出 n 阶 魔 方 阵 , 魔 方 阵 的 行 、 列 、 对 角 线 的 和 全 部 相 等 且 由 数 字 1 ∼ n ∗ n 构 成 。 输出n阶魔方阵,魔方阵的行、列、对角线的和全部相等且由数字1\sim n*n构成。 n线1nn

题解:

构 成 魔 方 阵 的 方 法 是 把 1 放 在 第 一 行 中 间 , 再 在 右 上 角 放 下 它 接 下 来 一 个 数 字 , 右 边 越 界 就 从 最 左 边 开 始 , 上 面 越 界 就 从 最 下 面 开 始 。 右 上 角 有 数 字 就 放 在 正 下 方 , 记 住 这 个 结 论 然 后 模 拟 即 可 。 构成魔方阵的方法是把1放在第一行中间,再在右上角放下它接下来一个数字,右边越界就从最左边开始,上面越界就从最下面开始。右上角有数字就放在正下方,记住这个结论然后模拟即可。 1

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,a[15][15]={0};
	int row,col;
	scanf("%d",&n);
	int i=0,j=n/2;
	for(int k=1;k<=n*n;k++){
		a[i][j]=k;
		row=i-1;
		col=j+1;
		if(row<0) row+=n;
		if(col>=n) col-=n;
		if(a[row][col]!=0){
			row=i+1;
			col=j;
		}
		i=row;j=col;
	}
	
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			printf("    %d",a[i][j]);
		}
		puts("");
	}
	return 0;
}

7-7 构造回文数

题目描述:

输 入 一 个 数 , 将 它 本 身 反 转 后 加 到 原 数 上 , 若 为 回 文 数 即 停 止 , 若 不 为 则 重 复 此 操 作 , 若 10 次 内 得 不 到 回 文 数 则 停 止 。 输入一个数,将它本身反转后加到原数上,若为回文数即停止,若不为则重复此操作,若10次内得不到回文数则停止。 10

题解:

此 题 依 然 为 模 拟 题 , 只 是 在 字 符 串 的 处 理 上 需 要 下 一 点 点 功 夫 , 可 以 单 独 开 一 个 函 数 来 判 断 是 否 回 文 。 此题依然为模拟题,只是在字符串的处理上需要下一点点功夫,可以单独开一个函数来判断是否回文。

#include<bits/stdc++.h>
#define MAXN 2010
using namespace std;
int t[MAXN];
bool check(string s){
	for(int i=0;i<s.size()/2;i++) if(s[i]!=s[s.size()-1-i]) return false;
	return true;
}
string add(string a,string b){
	reverse(a.begin(),a.end());
	reverse(b.begin(),b.end());
	if(a.size()<b.size()) swap(a,b);
	int n=a.size(),m=b.size();
	for(int i=0;i<m;i++) t[i]=a[i]-'0'+b[i]-'0';
	for(int i=m;i<n;i++) t[i]=a[i]-'0';
	for(int i=0;i<n;i++){
		if(t[i]<10) continue;
		t[i+1]+=t[i]/10;
		t[i]=t[i]%10;
	}
	string ans;
	if(t[n]!=0) ans.push_back(t[n]+'0');
	for(int i=n-1;i>=0;i--) ans.push_back(t[i]+'0');
	return ans; 
}
int main(){
	string s;
	cin>>s;
	for(int i=1;i<=10;i++){
		if(check(s)){
			cout<<s<<" is a palindromic number.";
			return 0;
		}
		string t(s);
		reverse(t.begin(),t.end());
		string sum=add(s,t);
		cout<<s<<" + "<<t<<" = "<<sum<<endl;
		s=sum;
	}
	if(check(s)) cout<<s<<" is a palindromic number.";
	else cout<<"Not found in 10 iterations.";
	return 0;
}

7-8 CPA最强连续素数(我真的是签到题O(∩_∩)O !)

题目描述:

输 出 小 于 等 于 n 的 三 个 最 大 的 连 续 素 数 。 输出小于等于n的三个最大的连续素数。 n

题解:

首 先 连 续 三 个 素 数 只 有 可 能 为 奇 数 ; 首先连续三个素数只有可能为奇数;

其 次 只 有 5 这 一 个 以 5 结 尾 的 奇 数 为 素 数 , 其 余 的 全 为 合 数 ; 其次只有5这一个以5结尾的奇数为素数,其余的全为合数; 55

于 是 我 们 发 现 , 只 有 3 、 5 、 7 这 一 种 可 能 , 其 余 的 都 会 因 为 几 十 五 的 缺 失 而 构 不 成 三 个 连 续 的 素 数 。 于是我们发现,只有3、5、7这一种可能,其余的都会因为几十五的缺失而构不成三个连续的素数。 357

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	scanf("%d",&n);
	if(n>=7) puts("3 5 7");
	else puts("小伙汁 不讲武德 耗子尾汁");
	return 0;
}

7-9 中位数

题目描述:

n 个 数 每 次 可 以 选 择 其 中 一 个 数 加 上 1 , 最 多 能 加 k 次 , 问 最 终 数 列 的 中 位 数 最 大 为 多 少 ? n个数每次可以选择其中一个数加上1,最多能加k次,问最终数列的中位数最大为多少? n1k

题解:

此 题 因 为 满 足 答 案 一 定 在 输 入 的 n 个 数 的 最 小 值 和 最 大 值 + k 之 间 , 而 且 答 案 一 定 满 足 单 调 性 , 所 以 采 用 二 分 答 案 的 办 法 , 在 初 始 的 中 位 数 m 和 m + k 之 间 二 分 答 案 。 此题因为满足答案一定在输入的n个数的最小值和最大值+k之间,而且答案一定满足单调性,所以采用二分答案的办法,在初始的中位数m和m+k之间二分答案。 n+kmm+k

#include<bits/stdc++.h>
#define MAXN 200010
using namespace std;
int a[MAXN],n,k;
inline bool check(int mid){
	int s=0;
	for(int i=n/2;i<n;i++){
		if(a[i]<mid){
			s+=mid-a[i];
			if(s>k) return false;
		}
	}
	return true;
}
int main(){
	while(scanf("%d%d",&n,&k)){
		for(int i=0;i<n;i++) scanf("%d",&a[i]);
		sort(a,a+n);
		int l=a[n/2],r=a[n/2]+k,ans;
		while(l<=r){
			int mid=(l+r)/2;
			if(check(mid)){
				ans=mid;
				l=mid+1;
			}
			else r=mid-1;
		}
		printf("%d\n",ans);
	}
	return 0;
}

7-10 士兵排队

题目描述:

输 入 士 兵 的 坐 标 , 找 到 士 兵 紧 密 地 排 成 一 行 所 需 要 移 动 的 最 少 步 数 。 输入士兵的坐标,找到士兵紧密地排成一行所需要移动的最少步数。

题解:

此 题 为 较 为 明 显 的 贪 心 , 首 先 看 y 轴 方 向 , 找 到 所 有 y 坐 标 的 中 位 数 即 可 ( 偶 数 个 数 需 要 比 较 一 下 中 间 两 个 数 的 最 终 步 数 大 小 ) 。 此题为较为明显的贪心,首先看y轴方向,找到所有y坐标的中位数即可(偶数个数需要比较一下中间两个数的最终步数大小)。 yy

x 轴 方 向 稍 微 复 杂 一 点 , 我 们 设 最 终 的 位 置 从 k 开 始 到 k + n − 1 结 束 , 则 列 出 方 程 x轴方向稍微复杂一点,我们设最终的位置从k开始到k+n-1结束,则列出方程 xkk+n1

S = ∣ X 0 − k ∣ + ∣ X 1 − ( k + 1 ) ∣ + ∣ X 2 − ( k + 2 ) ∣ + ⋯ + ∣ X n − 1 − ( k + ( n − 1 ) ) ∣ S=|X_0-k|+|X_1-(k+1)|+|X_2-(k+2)|+\dots+|X_{n-1}-(k+(n-1))| S=X0k+X1(k+1)+X2(k+2)++Xn1(k+(n1))

变 形 得 : 变形得: :

S = ∣ X 0 − k ∣ + ∣ ( X 1 − 1 ) − k ∣ + ∣ ( X 2 − 2 ) − k ∣ + ⋯ + ∣ ( X n − 1 − ( n − 1 ) ) − k ∣ S=|X_0-k|+|(X_1-1)-k|+|(X_2-2)-k|+\dots+|(X_{n-1}-(n-1))-k| S=X0k+(X11)k+(X22)k++(Xn1(n1))k

以 上 题 解 部 分 来 自 博 客 以上题解部分来自博客 https://blog.csdn.net/designer_/article/details/5475498

#include<bits/stdc++.h>
#define MAXN 10010
using namespace std;
struct node{
	int x,y;
}s[MAXN],b[MAXN];
bool cmpx(node a,node b){
	return a.x<b.x;
}
bool cmpy(node a,node b){
	return a.y<b.y;
}
int main(){
	int n;
	int xx,yy;
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d%d",&s[i].x,&s[i].y);
	sort(s+1,s+1+n,cmpy);
	yy=s[(n+1)/2].y;
	memcpy(b,s,sizeof(b));
	sort(b+1,b+1+n,cmpx);
	for(int i=1;i<=n;i++) b[i].x=b[i].x-i+1;
	sort(b+1,b+1+n,cmpx);
	xx=b[(n+1)/2].x;
	sort(s+1,s+1+n,cmpx);
	long long ans=0;
	for(int i=1;i<=n;i++) ans+=abs(s[i].x-(xx+i-1))+abs(s[i].y-yy);
	
	printf("%lld",ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值