【洛谷算题】顺序,分支,循环结构部分题目分享
P5707 【深基2.例12】上学迟到

- 问的是最晚,也就是说到学校是8:00 ,求出发时间
- 路程时间>=8hour
用路程时间减去8huor ,在从24:00往后扣
- 路程时间<8hour
从8:00往后扣时间
- 总时间要换成分钟
S总 : s/v+10 ,很明显要用double
- 输出格式 HH:MM
用%02d即可
int main()
{double s,v;cin>>s>>v;double sum=ceil(s/v)+10;if(sum<8*60)//在今天出发{int hour=sum/60;//换算成小时int minute=(int)sum%60;//换算成分钟if(minute)//有分钟{hour=8-hour-1;//顺便用ta来记录小时的时间minute=60-minute;//记录分钟}else{hour=8-hour;}printf("%02d:%02d",hour,minute);}//else//从昨天出发{sum-=480;int hour=sum/60;//换算成小时int minute=(int)sum%60;//换算成分钟if(minute)//有分钟{hour=24-hour-1;//顺便用ta来记录小时的时间minute=60-minute;//记录分钟}else{hour=24-hour;//输出一个 24 小时制下的时间}printf("%02d:%02d",hour,minute);}return 0;
}- 要用到ceil函数,ceil遇到带小数的向上取整,整型类型的不变

ceil(3.14)=4
ceil(-3.14)=-3;
ceil(5)=5;因为要想上取整,如果是单纯的 double sum=s/v+10;


中间差了1分钟 ,由于int minute=(int)sum%60;//换算成分钟 ,需要是int 类型才能% ,导致100/99= 1点几,这里就成1了,所以这里我们要向上取整,也就是说在这里 ,1点几分钟 ,我们把它当作2分钟,这样就满足了题意了
改成这样 :
double s,v;cin>>s>>v;double sum=ceil(s/v)+10;
- 注意 :输出一个 24 小时制下的时间,是24减,不是12减
P1009 [NOIP 1998 普及组] 阶乘之和

思路 :

一个数组prev来保存每次的乘积,一个数组sum来加上每次的乘积
prev就要面对高精度乘法 :prev数组=prev数组*一个数(数组的每一位都要乘以这个数,还要模拟进位)
sum就要面对高精度加法 : sum数组=sum数组+=prev数组
这样最后sum数组中逆序输出存的字就是最后的结果
(既然要逆序输出 ,所以肯定要有两个数记录两个数组的最高位 : len1 ,len2)
int main()
{int n;cin>>n;arr1[1]=1;arr2[1]=1;//先给一个1,因为2!是从2算到1,而1!,就已经在1了,相当于arr1已经存了当前的1!的乘积,、arr2已经加上了1!的乘积for(int i=2;i<=n;i++){func(i);addfunc();}for(int i=len2;i>0;i--){cout<<arr2[i];}return 0;
}- 既然是对数组操作,两个数组就放在全局中
- 这里arr1==prev,arr2==sum
- arr1[1]=1;arr2[1]=1;先给一个1,因为2!是从2算到1,而1!,就已经在1了,相当于arr1已经存了当前的1!的乘积,、arr2已经加上了1!的乘积
func(i) 计算n! ,addfunc(),加上每次的n!
#include<bits/stdc++.h>
using namespace std;int arr1[200];//n!
int arr2[200];//S=1!+2!+3!+⋯+n!int len1=1;//记录arr1数组的最高位
int len2=1;//记录arr2数组的最高位void func(int n)//高精度模拟乘法 算n!
{//n要乘以arr1,现在arr1代表着(n-1)!//在里就要用高精度算法//一个数乘以一个数组int carry=0;//记录要进的位for(int i=1;i<=len1;i++)//让数组的每一位都乘以这个数字,但i要小于多少呢{arr1[i]=arr1[i]*n+carry;carry=arr1[i]/10;arr1[i]%=10;}//万一进位carry还有值while(carry){arr1[++len1]=carry%10;carry/=10;}
}//走到这里来,arr1已经存了n!了;
//我们再只需要用arr2再加上arr1的值就行
//数组加数组
void addfunc()
{int maxi=max(len1,len2)+1;//加法最多进一位,可以拿数字模拟一下for(int i=1;i<=maxi;i++){arr2[i]+=arr1[i];arr2[i+1]+=arr2[i]/10;arr2[i]%=10;}while(maxi>0&&arr2[maxi]==0)//如果说用不到进位{maxi--;}len2=maxi;//更新arr2的最高位
}
P1980 [NOIP 2013 普及组] 计数问题

这个题放在这里主要是有个很好的方法
- 普通方法
int count1 = 0;
int x = 0;void func(int n)//记录一个数字中出现了几次x
{while (n){int x1 = n % 10;if (x1 == x){count1++;}n /= 10;}
}
count1和x定为全局
- count函数

int main()
{int arr[] = { 1,12,23,54,5,12,11,51 };int ret=count(arr, arr+sizeof(arr)/sizeof(arr[0]), 1);cout << ret << endl;string s1("11223545121151");ret = count(&s1[0], &s1[0] + s1.size(), '1');cout << ret;
return 0;
}
我们可以把每个数字都转成string,这样我们就能用count函数帮我们统计(字符)个数
int main()
{int n,x;cin>>n>>x;int total=0;for(int i=1;i<=n;i++){string s1=to_string(i);//把每个数字都转成string,这样我们就能用count函数帮我们统计个数total+=count(s1.begin(),s1.end(),x+'0');}cout<<total;return 0;
}P1217 [USACO1.5] 回文质数 Prime Palindromes

思路 :
先判段是不是回文数,在判断是不是质数,因为质数判断起来要走循环
判断质数简单:
bool isPrime(int num)
{if(num<2)return false;if(num==2||num==3)return true;if(num%2==0)return false;for(int i=3;i*i<=num;i+=2){if(num%i==0)return false;}return true;
}判断回文数 :
- way one :
转换成用string来判断
void func(int num)//思路一 : 用string来判断 ,用这种方式时间会超
{string tmp=to_string(num);int begin=0;int end=tmp.size()-1;while(begin<=end){if(tmp[begin]!=tmp[end]){return ;}begin++;end--;}cout<<num<<endl;
}用这种方式时间会超
- way two :
bool func1(int num)//思路二
{if(num==0||num%10==0)//0/120/20....return false;int half=0;while(num>half){half=half*10+num%10;num/=10;}return half==num||half/10==num;
}
所以这两种情况都要考虑到
return half==num||half/10==num;