字符串 APPAPT 中包含了两个单词 PAT,其中第一个 PAT 是第 2 位( P),第 4 位(A),第 6 位(T);第二个 PAT 是第 3 位( P),第 4 位(A),第 6 位(T)。
现给定字符串,问一共可以形成多少个 PAT?
输入格式:
输入只有一行,包含一个字符串,长度不超过10^5 ,只包含 P、A、T 三种字母。
输出格式:
在一行中输出给定字符串中包含多少个 PAT。由于结果可能比较大,只输出对 1000000007 取余数的结果。
输入样例:
APPAPT
输出样例:
2
原题链接
思考
注意点
AC1
#include
int main(){
char str[100010];
int i,left[100010]={0}; //每一位左边含P的个数
gets(str); //读入字符串
int len=strlen(str); //长度
for(i=0;i<len;i++){
if(i>0) left[i]=left[i-1]; //继承上一位的位置
if(str[i]=='P') left[i]++;
}
int sum=0,right=0; //sum为答案,right记录右边T的个数
for(i=len-1;i>=0;i--){
if(str[i]=='T'){
right++;
} else if(str[i]=='A'){
sum=(sum+left[i]*right)%1000000007; //累计乘积
}
}
printf("%d\n",sum);
return 0;
}
AC2
#include
int main(){
int LIM=1000000007;
int P=0,PA=0,PAT=0;
char c;
while((c=getchar())!= '\n'){
if(c=='P') P++;
if(c=='A') PA=(PA+P)%LIM;
if(c=='T') PAT=(PAT+PA)%LIM;
}
printf("%d",PAT);
return 0;
}
给定任一个各位数字不完全相同的 4 位正整数,如果我们先把 4 个数字按非递增排序,再按非递减排序,然后用第 1 个数字减第 2 个数字,将得到一个新的数字。一直重复这样做,我们很快会停在有“数字黑洞”之称的 6174,这个神奇的数字也叫 Kaprekar 常数。
例如,我们从6767开始,将得到
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
... ...
现给定任意 4 位正整数,请编写程序演示到达黑洞的过程。
输入格式:
输入给出一个 (0,10^4) 区间内的正整数 N。
输出格式:
如果 N 的 4 位数字全相等,则在一行内输出 N - N = 0000;否则将计算的每一步在一行内输出,直到 6174 作为差出现,输出格式见样例。注意每个数字按 4 位数格式输出。
输入样例 1:
6767
输出样例 1:
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
输入样例 2:
2222
输出样例 2:
2222 - 2222 = 0000
原题链接
思考
注意点
AC1——C++
#include
#include
using namespace std;
int i;
bool cmp(int a,int b){ //递减排序
return a>b;
}
void to_array(int n,int num[]){ //将n的每一位存到num数组中
for(i=0;i<4;i++){
num[i]=n%10;
n/=10;
}
}
int to_number(int num[]){ //将num数组转换为数字
int sum=0;
for(i=0;i<4;i++){
sum=sum*10+num[i];
}
return sum;
}
int main(){
int n,MAX,MIN,str[5];
scanf("%d",&n);
while(1){
to_array(n,str); //将n转换为数组
sort(str,str+4); //对num数组中元素从小到大排序
MIN=to_number(str); //获取最小值
sort(str,str+4,cmp); //对num数组中元素从大到小排序
MAX=to_number(str); //获取最大值
n=MAX-MIN; //得到下一个数
printf("%04d - %04d = %04d\n",MAX,MIN,n); //注意格式
if(n==0||n==6174) break; //如果下个数是0或6174则退出
}
return 0;
}
AC2——C
#include
int cap(const void *a, const void *b){
return *(int*)b - *(int*)a;
}
int stor(int n){
int zoo[4] = {n/1000, n%1000/100, n%100/10, n%10};
qsort(zoo, 4, sizeof(int), cap);
return zoo[0] * 1000 + zoo[1] * 100 + zoo[2] * 10 + zoo[3];
}
int rever(int n){
return n/1000 + n%1000/100 * 10 + n%100/10 * 100 + n%10 * 1000;
}
int main(){
int n;
scanf("%d", &n);
do{
n = stor(n);
printf("%04d - %04d = %04d\n", n, rever(n), n - rever(n));
n = n - rever(n);
}while(n != 0 && n != 6174) ;
return 0;
}
令 Pi表示第 i 个素数。现任给两个正整数 M≤N≤10^4,请输出PM到PN的所有素数。
输入格式:
输入在一行中给出 M 和 N,其间以空格分隔。
输出格式:
输出从 PM 到 PN的所有素数,每 10 个数字占 1 行,其间以空格分隔,但行末不得有多余空格。
输入样例:
5 27
输出样例:
11 13 17 19 23 29 31 37 41 43
47 53 59 61 67 71 73 79 83 89
97 101 103
原题链接
思考
注意
if(pNum>=n) break;
这是由于题目只要求输出第m~n个素数,因此超过n个素数之后的就不用保存了。#include
typedef int bool; //自定义bool
#define false 0
#define true 1
int prime[1000001],pNum=0; //prime数组存放数组,pNum为素数个数
bool p[1000001]={0}; //如果i为素数,p[i]为false;否则为true
void Find_Prime(int n){
int i,j;
for(i=2;i<1000001;i++){
if(p[i]==false){
prime[pNum++] = i;
if(pNum >= n) break; //只需要 n 个素数,超过即可结束 ,核心!!
for(j=i+i;j<1000001;j+=i){
p[j]=true;
}
}
}
}
int main(){
int M,N,i,count=0;
scanf("%d %d",&M,&N);
Find_Prime(N);
for(i=M;i<=N;i++){
printf("%d",prime[i-1]); //下标从 0 开始
count++;
if(count%10!=0 && i<N) printf(" "); //每行10个,行末无多余空格
else printf("\n");
}
return 0;
}
如果你是哈利·波特迷,你会知道魔法世界有它自己的货币系统 —— 就如海格告诉哈利的:“十七个银西可(Sickle)兑一个加隆(Galleon),二十九个纳特(Knut)兑一个西可,很容易。”现在,给定哈利应付的价钱 P 和他实付的钱 A,你的任务是写一个程序来计算他应该被找的零钱。
输入格式:
输入在 1 行中分别给出 P 和 A,格式为 Galleon.Sickle.Knut,其间用 1 个空格分隔。这里 Galleon 是 [0, 10^7] 区间内的整数,Sickle 是 [0, 17) 区间内的整数,Knut 是 [0, 29) 区间内的整数。
输出格式:
在一行中用与输入同样的格式输出哈利应该被找的零钱。如果他没带够钱,那么输出的应该是负数。
输入样例 1:
10.16.27 14.1.28
输出样例 1:
3.2.1
输入样例 2:
14.1.28 10.16.27
输出样例 2:
-3.2.1
原题链接
样例解释
样例1
样例2
思考
注意点
AC
#include
int main() {
int Galleon, Sickle, Knut, P, A, change;
scanf("%d.%d.%d", &Galleon, &Sickle, &Knut);
P = (Galleon * 17 + Sickle) * 29 + Knut; //价钱
scanf("%d.%d.%d", &Galleon, &Sickle, &Knut);
A = (Galleon * 17 + Sickle) * 29 + Knut; //实付
change = A - P;
if (change < 0) {//钱不够
printf("-");
change = -change;
}
printf("%d.%d.%d\n", change / 29 / 17, change / 29 % 17, change % 29);
return 0;
}
让我们用字母 B 来表示“百”、字母 S 表示“十”,用 12…n 来表示不为零的个位数字 n(<10),换个格式来输出任一个不超过 3 位的正整数。例如 234 应该被输出为 BBSSS1234,因为它有 2 个“百”、3 个“十”、以及个位的 4。
输入格式:
每个测试输入包含 1 个测试用例,给出正整数 n(<1000)。
输出格式:
每个测试用例的输出占一行,用规定的格式输出 n。
输入样例 1:
234
输出样例 1:
BBSSS1234
输入样例 2:
23
输出样例 2:
SS123
原题链接
思考
AC1
#include
int main(){
int n,i,j;
scanf("%d",&n);
int num=0,ans[5];
while(n!=0){ //将n的每一位存入ans数组
ans[num]=n%10;
num++;
n=n/10;
}
for(i=num-1;i>=0;i--){ //从高位到低位输出
if(i==2){ //如果是百位
for(j=0;j<ans[i];j++){
printf("B"); //输出ans[i]个B
}
} else if(i==1){
for(j=0;j<ans[i];j++){
printf("S"); //输出ans[i]个S
}
} else{ //如果是个位
for(j=1;j<=ans[i];j++){
printf("%d",j);
}
}
}
return 0;
}
AC2
#include
int main(){
int N,i;
scanf("%d",&N);
int B = N/100; //存储百位
if(B != 0) { //输出B个B
for(i = 0;i < B;i++) printf("B");
}
int S = N % 100 / 10; //存储十位
if(S != 0) {
for(i = 0;i < S;i++) printf("S");
}
int G = N % 10; //存储个位
for(i=1;i<=G;i++) printf("%d",i);
return 0;
}