本周训练的题目主要跟csp的第一题挂钩。
前面的几个题目相对容易,主要是要注意在不确定输入多少个数值的情况下的解决方案。我归纳了java,c语言,c++三种语言的处理方法如下:
java
例如F - IO6计算下面每行数的和。
Input
输入包含多组数据,每组数据占一行。每行第一个数为整数N,后面有N个整数
Output
对于输入的每一行数,请分别对应输出每一行数的和。
Sample Input
4 1 2 3 4
5 1 2 3 4 5
Sample Output
10
15
import java.util.*;
public class Main {
public static void main(String args[]) {
Scanner cin = new Scanner(System.in);
int a, b;
while (cin.hasNext()) {//用hasNext()即可解决
int sum = 0;
a = cin.nextInt(); //确保只读下一个int类型的值
for(int i = 0;i < a;i++) {
b = cin.nextInt();
sum += b;
}
System.out.println("\n"+sum);
cin.nextLine();
}
}
}
C语言
例如K - Water3求实数的绝对值。
Input
输入数据有多组,每组占一行,每行包含一个实数。
Output
对于每组输入数据,输出它的绝对值,要求每组数据输出一行,结果保留两位小数。
#include<stdio.h>
int main()
{
double a;
while(scanf("%lf",&a)!=EOF){//不等于EOF即可
if(a>0)
{
printf("%.2f\n",a);//注意C语言中取两位小数的表示方法
}
else
{
printf("%.2f\n",-a);
}
}
return 0;
}
C++
例如M - Water10,输入三个字符后,按各字符的ASCII码从小到大的顺序输出这三个字符。
#include<iostream>
using namespace std;
void swap(int&a, int&b) {
int c;
c = a;
a = b;
b = c;
}
int main() {
char a, b, c;
while (cin>>a) {//只需要cin>>a即可
cin >> b >> c;
if (a > b) { swap(a, b); }
if (a > c) { swap(a, c); }
if (c < b) { swap(c, b); }
cout << a << " " << b << " " << c << endl;
}
return 0;
}
在正式解决问题之前,回顾一下C++的各种输入输出,参考C++中的字符串的输入输出
下面是于我来说容易出错的几个题目:
L - Water6
主要目的:
对于给定的一个字符串,统计其中数字字符出现的次数。
Input
输入数据有多行,第一行是一个整数n,表示测试实例的个数,后面跟着n行,每行包括一个由字母和数字组成的字符串。
Output
对于每个测试实例,输出该串中数值的个数,每个输出占一行。
Sample Input
2
asdfasdf123123asdfasdf
asdf111111111asdfasdfasdf
Sample Output
6
9
C++代码解答
#include <iostream>
using namespace std;
int main()
{
int n,i,s;
char x;
cin>>n;
getchar();//从缓冲区读走一个字符,相当于清除缓冲区,因为之前已经输入过了值
for(i=0;i<n;i++)
{
sum=0;
while((x=getchar())!='\n')//遇到回车结束这一行的循环
{
if(x>='0'&&x<='9')
sum++;
}
cout<<sum<<endl;//得到该行的数值总个数
}
return 0;
}
N - 十六进制
给定两个十六进制整数a和b,输出他们的和
Input
输入多组数据,以EOF作为数据的结束
每组数据在一行中包含了两个十六进制整数a和b。
Output
对于每一组数据,以十进制输出a+b的和。
每组输出占用一行。
Sample Input
1 9
A B
a b
Sample Output
10
21
21
首先回顾一下各种语言关于十六进制转十进制的方法,参考进制转换之十六进制转十进制(C/C++/Java)
C++代码解答
#include<iostream>
using namespace std;
int main() {
int m,n;
while(cin >> hex >> m >> n) //以十六进制形式输入
cout << dec << m+n << endl; //以十进制方式输出
system("pause");
return 0;
}
O - 快速幂板子题(重点!)
给出3个正整数A B C,求A^B Mod C。 例如,3 5 8,3^5 Mod 8 = 3。
Input
3个正整数A B C,中间用空格分隔。(1 <= A,B,C <= 10^9)
Output
输出计算结果
Sample Input
3 5 8
Sample Output
3
该题的关键在于10^9可能会超出数据范围,可以用快速幂来解决,先来了解一下快速幂!
本题主要用到上图中的带模快速幂,注意long long的最大值为9223372036854775807(即2^63-1),long long的最小值为-9223372036854775808(即-2^63),其他相关数据范围参考char,short ,int ,long,long long,unsigned long long数据范围
C++代码
#include<iostream>
#include <math.h>
using namespace std;
long long quick_pow(long long a, long long x, long long MOD) {
long long ans = 1;
for (; x; x >>= 1, a = a * a%MOD)//每次进行x的右移,并将a变为上一次a的平方,实现底数为a,2的幂次方为指数的一项分治出来的乘项
if (x & 1)//如果x是奇数那么x&1的值就是1,如果x是偶数那么x&1=0,当x为奇数时,执行下一步
ans = ans * a%MOD;//此时x化为二进制的最后一项必为1,即要算上该项关于a的幂的1次方,再乘以移位之前这么算出来的乘积
return ans;//最后得到的结果是用分治实现的各项乘积之积
}
int main() {
long a, b, c;
cin >> a >> b >> c;
cout << quick_pow(a,b,c) << endl;
return 0;
}