赞
踩
博主是ZISU在校学生,刚学C/C++才2个多月,为了记录自己的学习过程和分享思路,故写一些博客。当然我的代码许多时候不是最优解,欢迎大家评论留言一起学习。如果有友友想提交这些题试试自己的思路啥的,可以私我,因为外校友友应该是登陆不进咱们的平台的。对于搜索到本博客的同校友友,切勿直接照抄,理解了再自己码字码上去。
思路:直接写,只不过这次把处理封装成一个自定义函数
参考题解:
- #include <iostream>
- using namespace std;
- int f(int x){
- if(x < 1) return x;
- else if(x < 10) return 2*x-1;
- else return 3*x-11;
- }
- int main(){
- //问题 A: 分段函数求解
- int x;cin >> x;
- cout << f(x) << endl;
- return 0;
- }
思路:求最大公约数咱们这个阶段使用辗转相除法最优
参考题解:
- #include <iostream>
- using namespace std;
- int gcd(int x,int y){ //辗转相除法
- int temp;
- if(x < y){
- temp = x;
- x = y;
- y = temp;
- }
- while(x%y!=0){
- temp = x % y;
- x = y;
- y = temp;
- }
- return y;
- }
- int main(){
- //问题 B: 最大公约数
- int x,y;cin >> x >> y;
- cout << gcd(x,y) << endl;
- return 0;
- }
说明:最大公约数同上题,找最小公倍数可以通过最大公约数直接算出,但我这里使用了暴力寻找的方法
参考题解:
- #include <iostream>
- #include <cmath>
- using namespace std;
- int gcd(int x,int y){ //辗转相除法
- int temp;
- if(x < y){
- temp = x;
- x = y;
- y = temp;
- }
- while(x%y!=0){
- temp = x % y;
- x = y;
- y = temp;
- }
- return y;
- }
- int lcd(int x,int y){ //暴力寻找
- for(int i = max(x,y);i<=x*y;i++) if(i%x==0&&i%y==0) return i;
- }
-
- int main(){
- //问题 C: 最大公约数和最小公倍数
- int x,y;cin >> x >> y;
- cout << gcd(x,y) << " " << lcd(x,y) << endl;
- return 0;
- }
思路:暴力寻找即可,其中需要写一个判断是否为素数的自定义函数
参考题解:
- #include <iostream>
- using namespace std;
- bool is_Prime(int n){ //判断是否为素数
- if(n == 1) return false; //1不是素数
- if(n == 2) return true; //2为素数
- for(int i = 2;i*i<=n;i++) if(n%i==0) return false;//如果有因子,则不是素数
- return true; //没有因子,则为素数
- }
-
- int main(){
- //问题 D: Goldbach's conjecture
- for(int i = 4;i<=100;i+=2){
- cout << i << "=";
- for(int j = 2;j<i;j++){
- if(!is_Prime(j)) continue; //若j不为素数则继续找
- if(is_Prime(i-j)){ //如果j为素数且i-j也为素数,则输出
- cout << j << "+" << i-j << endl;
- break;
- }
- }
- }
- return 0;
- }
思路:上一题已经写了判断是否为素数的自定义函数,这个题再加上写一个判断是否为回文数的函数即可。判断既是素数又是回文数则count++,最终输出count
参考题解:
- #include <iostream>
- using namespace std;
- bool is_Prime(int n){ //判断是否为素数
- if(n == 1) return false;
- else if(n == 2) return true;
- for(int i = 2;i*i<=n;i++) if(n%i==0) return false;
- return true;
- }
- bool is_Huiwen(int n){ //判断是否为回文数
- int temp = n,sum = 0; //左右颠倒数字判断是否相等
- while(temp != 0){
- sum = sum*10 + temp %10;
- temp /= 10;
- }
- if(sum==n) return true;
- else return false;
- }
- int main(){
- //问题 E: 素数回文数的个数
- int n,count = 0;cin >> n;//count计数
- //若找到既是素数又是回文数的,count加一
- for(int i = 11;i<=n;i++) if(is_Prime(i)&&is_Huiwen(i)) count++;
- cout << count << endl;
- return 0;
- }
思路:同样也是遍历判断,注意这里写判断素数的自定义函数的时候,不要忘记输入的数可能是1和2,1和2一般要特殊处理
参考题解:
- #include <iostream>
- using namespace std;
- bool is_Prime(int n){ //判断是否为素数
- if(n == 1) return false;
- else if(n == 2) return true;
- for(int i = 2;i*i<=n;i++) if(n%i==0) return false;
- return true;
- }
- int main(){
- //问题 F: 判决素数个数
- int x,y,count = 0;cin >> x >> y;//count用于计数
- for(int i = x;i<=y;i++) if(is_Prime(i)) count++;
- cout << count << endl;
- return 0;
- }
思路:注意题目是从右往左找,直接循环整除10找即可
参考题解:
- #include <iostream>
- using namespace std;
- int find(int n,int k){ //实现找digit的函数
- int count = 1,temp = n;//count初始化为1,count代表从右往左第count个数字
- while(temp != 0){
- if(count == k) return temp%10;//先判断count是否等于k,count再++
- count++;
- temp /= 10;
- }
- }
- int main(){
- //问题 G: digit函数
- int n,k;cin >> n >> k;
- cout << find(n,k) << endl; //函数调用
- return 0;
- }
相对其他题来说比较难,这里给出两种思路
思路1:以字符串形式读入小数,然后从小数点后开始构造分子和分母,特别地,此处后续对分子分母的约分直接调用头文件<algorithm>的__gcd()函数用于求最大公约数,其实像前面的题一样写一个gcd()函数也很快的
参考题解1:
- #include <iostream>
- #include <algorithm>
- #include <cstring>
- using namespace std;
- char ch[12];
- void transform(){
- int fenzi = 0, fenmu = 1;
- cin >> ch;
- for(int i = 2;i<strlen(ch);i++) {
- if (ch[i] >= '0' && ch[i] <= '9') {
- fenmu *= 10; //构造分母
- fenzi = fenzi * 10 + ch[i] - '0';//构造分子
- }
- }
- if (fenmu == 10 && fenzi == 0) {//如果输入0.0则输出0/1
- cout << "0/1" << endl;
- return;
- }
- //找最大公约数约分
- int _gcd = __gcd(fenmu,fenzi);
- fenmu = fenmu / _gcd;
- fenzi = fenzi / _gcd;
- cout << fenzi << "/" << fenmu << endl;
- }
- int main() {
- //问题 H: 小数化分数1
- int n;
- cin >> n;
- getchar();//读掉最后的换行符
- while(n--) transform();
- return 0;
- }
思路2:以双精度浮点数double的形式读入数据,根据题意小数位不会超过9位,构造分母为1e9,构造分子为数据乘以1e9,但是注意此处分子的构造会丢失精度,需要在乘以1e9后再加上0.5解决精度丢失问题,然后约分输出即可
参考题解2:
- #include <iostream>
- using namespace std;
- int gcd(int x,int y){ //求最大公约数函数
- int temp;
- if(x<y){ //确保x>y
- temp = x;
- x = y;
- y = temp;
- }
- while(x%y != 0){ //辗转相除法求最大公约数
- temp = x%y;
- x = y;
- y = temp;
- }
- return y;
- }
- int main(){
- //问题 H: 小数化分数1
- int n;cin >> n;
- double dec;
- int num;
- while(n--){
- cin >> dec;
- num = dec*1000000000+0.5; //+0.5是为了解决精度丢失的问题
- if(num==0) cout << "0/1" << endl;//num为0输出“0/1”
- else{
- int gcdnum = gcd(1000000000,num);//找num和1e9的最大公约数
- cout << num/gcdnum << "/" << 1000000000/gcdnum << endl; //输出的时候,分子分母同时除以最大公约数
- }
- }
- return 0;
- }
又算一个难题,难点在字符匹配这一个阶段
思路:操作1比较好处理,注意刚开始给buf[]数组长度时尽可能大一些,将两个字符串通过下标(索引)拼接;操作3是最好处理的,我们都知道数组遇到'\0'会认为已经到头了,我们只需计算数组buf长度与len的差,直接找到对应下标,修改值为'\0';操作2是匹配字符串,最好写一个函数,我这里匹配的思路是暴力匹配
参考代码:
- #include <iostream>
- #include <cstring>
- using namespace std;
- int lenbuf,lens;
- void match(char buf[10005],char s[105]){ //字符串匹配
- lenbuf = strlen(buf);lens = strlen(s);
- int maxk = 0;
- for(int i = 0;i<lenbuf;i++){ //暴力匹配
- for(int j = 0;j<lens;j++){
- int k;
- for(k = 0;k<lens;k++){ //如果buf[i+k]和s[j+k]对应都相等,k++
- if(buf[i+k] != s[j+k]) break;
- if(buf[i+k] == '\0') break;
- }
- if(k > maxk) maxk = k; //求出所有k中最大的那个k,就是我们要找的值
- }
- }
- cout << maxk << endl;
- }
- int main(){
- //问题 I: 字符串匹配
- char buf[10005],s[105];
- int m,op,len;
- while(~scanf("%s",buf)){//~scanf() 等价于 scanf()!=EOF 也等价于 scanf() == 1
- cin >> m;
- while(m--){
- cin >> op; //op为操作数:1或2或3
- if(op == 1){
- lenbuf = strlen(buf);
- cin >> s;
- lens = strlen(s);
- for(int i = 0;i<lens;i++) buf[lenbuf+i] = s[i];//拼接字符串
- buf[lenbuf+lens] = '\0';//找到buf的新长度,输入结束符'\0'
- }else if(op == 2){
- cin >> s;
- match(buf,s); //调用函数
- }else if(op == 3){
- cin >> len;
- lenbuf = strlen(buf);
- buf[lenbuf-len] = '\0'; //直接用结束符'\0'截断即可
- }
- }
- }
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。