A 求最小公倍数
#include<stdio.h>
int gcd(int a,int b)
{
return b>0?gcd(b,a%b):a;
}
int main()
{
int a,b;
while(~scanf("%d%d",&a,&b))
{
if(a==0&&b==0) break;
printf("%d\n",a*b/gcd(a,b));
}
return 0;
}
记住最大公约数的函数,然后最小公倍数等于两个数的乘积除以最大公约数,最大公约数函数是代码中的gcd函数
B 爱你一生一世
#include<stdio.h>
int gcd(int a,int b)
{
return b>0?gcd(b,a%b):a;
}
int main()
{
int k;
scanf("%d",&k);
while(k--)
{
int n,m;
scanf("%d%d",&n,&m);//礼物的件数和不喜欢的礼物的件数
if(m<2) printf("1\n");
else if(n==m) printf("0\n");
else
{
int a=(n-1)*n-(m-1)*m;
int b=n*(n-1);
int temp=gcd(a,b);
a/=temp;
b/=temp;
printf("%d/%d\n",a,b);
}
}
return 0;
}
这道题我非常感慨,因为以前对我来说确实是拦路虎,现在确实可以轻松写出来了
应用最大公约数函数,分式计算的话,就是分子分母同时除以最大公约数,如果分母等于1 ,就只需要输出分子
该题还需要推一下公式,选两件不同的礼物,至少有一件礼物是她喜欢的,反面是没有一件礼物是她喜欢的,用1减去反面的概率,就是我们要求的概率,很明显,反面的概率更容易求
公式如上,不喜欢的礼物数目小于2的话,选两件礼物,一定至少有一件礼物是她喜欢的,所以概率是1,如果所有礼物她都不喜欢,概率就是0(想起来,网上一个段子,她不是不喜欢这件礼物,只是不喜欢你哈哈)
甚至都不需要判断分母是否等于1,因为分母不可能等于1,如果分母等于1,只有一种情况,就是答案为1,但是答案为1的情况我们已经特判过了
C 奇偶校验
#include<stdio.h>
#include<string.h>
int main()
{
int n;
while(~scanf("%d",&n))
{
if(n==-1) break;
int a[10];
for(int i=1;i<=8;i++)
{
a[i]=n%2;
n/=2;
}
//for(int i=8;i>=1;i--) printf("%d",a[i]);
int cnt=0;
for(int i=8;i>=2;i--)
{
if(a[i]==1)
{
cnt++;
}
}
int b=0;
if(cnt%2==0) b=0;
else b=1;
if(b==a[1]) printf("Yes");
else printf("No");
printf("\n");
memset(a,0,sizeof a);
}
return 0;
}
进制转换的一道题目,对进制取模,然后除以进制,非常经典,记住这个讨论即可
注意这里下标是从0开始的(题干里面),所以我一开始还是非常奇怪的,为什么只算前面六位当数据位,原来从0开始数数到六是七位
思路就是把一个十进制数字转换成二进制数字,把每一位数字存在数组里面,然后根据题目要求模拟一下即可
D n!进制
#include<stdio.h>
int a[15];
void fact()
{
a[0]=1;
a[1]=1;
for(int i=2;i<=15;i++) a[i]=a[i-1]*i;
}
int main()
{
fact();
int n;
while(~scanf("%d",&n))
{
if(n==0)
{
puts("0");
continue;
}
int temp=0;
for(int i=15;i>=1;i--)
{
if(a[i]<=n)
{
temp=i;
break;
}
}
while(temp!=0)//最小是到1的阶乘
{
int ans=n/a[temp];
printf("%d",ans);
n%=a[temp];
temp--;
}
puts("");
}
return 0;
}
不知道是什么原因,挺难理解这个题目的意思的
题目的意思是说,给定一个十进制数字,要求我们输出这个十进制数字的n!进制数字。这个定义比较奇怪,光看题干的21的例子,我还以为是把数位上的数字乘以该数字的阶乘,然后累加,累加的结果就是答案
但是事实上,10按照这个思路应该是1,100按照这个思路也是1,但是样例分别是120和4020
权重乘以系数就是总共的大小,观察一下数据范围,数据范围是3628799,这个数字是10的阶乘减去1,权重乘以系数,表示数字大小,每一位上的系数,从高位一直输出到最低位就是答案
要优先处理最高位,因为权重最大,假设优先处理最低位,很有可能会导致系数非常大,与实际情乱矛盾
所以思路就是,找到比当前十进制数字小的最大的阶乘,然后除以该阶乘,表示的是最高位的系数,输出这个系数,十进制数字n对该阶乘取余,表示的是剩下的数字的大小,然后把阶乘变成下一个阶乘(比如说4的阶乘变成3的阶乘,3的阶乘变成2的阶乘),一直到阶乘是1的阶乘,表示操作结束,输出换行即可
在循环里我们除了使用 if 这种条件判断,还可以使用 continue 表示后面的都不考虑,直接下一次循环,也非常方便
前面的 fact 函数是用来求阶乘的,fact是 factorial 英文的前四个字母,表示阶乘
另外发现写c语言题目还是用 c 语言比较友好,不然我辛苦写却不符合学弟学妹的需求,还是有点无奈的哈哈
笔者都大二了,还是不能随手秒掉这些 c语言题目,还是非常惭愧啊
E ICPC
#include<stdio.h>
#include<string.h>
char s1[110],s2[110],s3[110];
int cnt[10];
int main()
{
int n;
while(~scanf("%d",&n))
{
if(n==0) break;
scanf("%s",s1+1);
scanf("%s",s2+1);
scanf("%s",s3+1);
char ans;
for(int i=1;i<=n;i++)
{
ans=s1[i];
if(s2[i]<ans) ans=s2[i];
if(s3[i]<ans) ans=s3[i];
printf("%c",ans);
cnt[ans-'A'+1]++;
}
printf("\n");
for(int i=1;i<=4;i++) printf("%d ",cnt[i]);
printf("%d\n",cnt[5]);
memset(cnt,0,sizeof cnt);
}
return 0;
}
算是简单的数组的使用
主要问题是空格……
还有就是不用c++的min函数确实写起来不是很熟练
输入字符的时候,空格也会读入,所以非常不方便,所以还是用字符串读入比较好,然后计数器数组每一次循环之后要重置,不然会影响下一次循环的结果
题目需要模拟的就是输入的数据里面,每一列的最小的字母,输出这个字母,然后给这个字母计数即可,注意输出的格式,防止PE
F coins
#include<stdio.h>
int dp[45][2];
int main()
{
dp[1][0]=1;//正面
dp[1][1]=1;//反面
for(int i=2;i<=40;i++)
{
dp[i][0]+=dp[i-1][1];
dp[i][1]+=(dp[i-1][0]+dp[i-1][1]);
}
int n;
while(~scanf("%d",&n))
{
if(n==0) break;
printf("%d\n",dp[n][0]+dp[n][1]);
}
return 0;
}
做不出来,简单的动态规划题目……
不包含连续的正面的方案数目。意思就是,只能是全部是反面,正反交替,或者是反面+正反交替
本来以为正面不好枚举答案,然后发现反面也不好枚举答案
DP来做这题,首先是DP集合表示什么意思,第一维表示的是有多少个硬币,第二维表示的是正面或者反面两种情况,我们需要做的是枚举所有情况
状态计算的时候,0表示正面,正面前面可以放反面
1表示反面,反面前面任意放
代码很短,但是得有动态规划的思路,才能做出来
G 因子和
#include<stdio.h>
int main()
{
long long n;
while(~scanf("%I64d",&n))
{
if(n==0) break;
long long ans=0;
for(int i=1;i*i<=n;i++)
{
if(n%i==0)
{
if(i==n/i) ans+=i;
else ans+=i+n/i;
}
}
printf("%I64d\n",ans);
}
return 0;
}
第一眼以为是前缀和,求1到n所有数字的和
直接按照题意模拟,用%lld输出,超时了,改成%I64d就过了
正解应该是要用算数基本定理的推论去分解质因数,然后套用公式求解
如果两个因子相等表示该数字是一个完全平方数,该因子只能被计算一次,如果不是的话就可以计算两次,分界点是输入的数字开根号
结语
总结就是,我感觉我C语言期末考试要爆零了,感觉一个题都做不来,慌……