3-1 得分 (UVa 1585)
题目:有一个客观的测试结果,如“OOXXOXXOOO”,一个“O”表示一个问题的正确答案,一个“X”表示一个错误的答案。这个测试的每个问题的分数是由它自己计算的,例如,第10个问题的得分是3,它是由它自己和它的前两个连续的O得到的。
因此,“OOXXOXXOOO”的分数是由“1 + 2 + 0 + 0 + 1 + 0 + 0 + 1 + 2 + 3”计算得到的10。
你要编写一个计算测试结果分数的程序。
提示:用一个flag标记是否是O开头
#include <iostream> using namespace std; int main(void) { string str; cin >> str; int len = str.length(); bool start = false; int count = 0; int sum = 0; for (int i = 0; i < len; i++){ if (str[i] == 'O'){ start = true; count++; } else if (str[i] == 'X') { start = false; count = 0; } if (start) { sum += count; } } }
3-2分子量 (UVa 1586)
题目大意:给出一种物质的分子式(不带括号),求分子量。本题中分子式只包含4种原子,分别为C、H、O、N,
原子量分别为12.01,1.008,16.00,14.01
提示:用数组保存四种原子的分子量,用flag标记当前位是字母还是数字。如果是数字,超过一位的,把每一位的数值从字符串中提取出来。用数组保存每一位的分子量。
#include <stdio.h> #include <string.h> #include <ctype.h> float ans[100]; float mass[] = {12.01, 1.008, 16.00, 14.01}; char str[10]; int len; int num(int pos, int len)//pos为数字开始的位置,len为分子式长度 { int temp; for (int i=pos;i<len;i++){ //获取数字长度,并存储到temp if(isdigit(str[i])){ temp=i; } else { break; } } int n = 0; for (int i=pos; i <=temp;i++){ //根据每一十进制位计算分子量 n = n * 10 + (str[i] - '0'); } return n - 1; //注意减一是因为最后计算的时候,字母本身占一倍 } int main(void) { int flag = 0; scanf("%s", str); len = strlen(str); for (int i = 0; i < len; i++){ if (str[i] == 'C'){ ans[i]=mass[0]; } if (str[i] == 'H'){ ans[i]=mass[1]; } if (str[i] == 'O'){ ans[i]=mass[2]; } if (str[i] == 'N'){ ans[i]=mass[3]; } if(isdigit(str[i])&&flag==0){ //初始状态flag = 0,直接进入if判断 ans[i]=ans[i-1] * num (i, len); //若该位为数字,则计算数字乘以前面元素的分子量 flag = 1; //做标记,表示计算数字,下次循环忽略此if判断 } if (isalpha(str[i])){ //若该位为字母,则标记flag = 0复位,方便下次循环进入上面if判断 flag = 0; } } float sum = 0; for (int i = 0; i<len;i++){ sum+=ans[i]; } printf("%.3f\n",sum); return 0; }
3-3 数数字(UVa1225)
#include <iostream> using namespace std; int main(void) { int sum[10] = {}; //sum[i]表示数字i的个数 for (int i = 1; i <= 10000; i++){ int j = i; while (j > 0){ int k; k = j % 10; //获取个位 sum[k]++; //个位数字的个数加一 j /= 10; //下一位 } } for (int i = 0; i < 10; i++){ cout << i << " : " << sum[i] << endl; } }
3-4周期串(UVa455)
题目:求一个串的最小循环节。
解题思路:
对一个字符串求其最小周期长度,那么,最小周期长度必定是字符串长度的约数,即最小周期长度必定能被字符串长度整除
其次,对于最小周期字符串,每位都能对应其后周期字串的每一位,
if(a[j]!=a[j%3])说明不对应,不是周期,进行下一位扫描。
#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> using namespace std; char str[104]; int main(void) { int n; while (~scanf("%d",&n)) while (n--){ scanf("%s", str); int len = strlen(str); for(int k, i = 1; i < len; i++){ if (len % i == 0 ) //若子串长度能够整除母串 for (k = i; k < len; k++) //开始匹配 if (str[i] != str[k%i]) //如果不能匹配 break; //则跳出 if (len == i) {//若全部匹配 cout << i; break; } } if (n) cout << endl; } }
3-8 循环小数(UVa202)
大致题意:
输入整数a(0<=a<=3000)和 b (1<=b<=3000),输出a/b的循环小数表示以及循环字节长度。例如a=5,b=43,小数表示为0.(116279069767441860465),循环字节长度为21
#include<stdio.h> #include<cstring> #include<algorithm> #include <iostream> #define HardBoy main() #define ForMyLove return 0; using namespace std; const int MYDD = 1103+1e4; int HardBoy { int quotient[MYDD]; int remainder[MYDD]; int u[MYDD]; int n, m, t; while(scanf("%d %d", &n, &m) != EOF) { t = n;/*3000以内*/ memset(quotient, 0, sizeof(quotient)); memset(u, 0, sizeof(u)); int cnt = 0; quotient[cnt++] = n/m; n %= m; //n为余数,循环前数组u[]被置0,!u[n]为真,进入循环 while(!u[n] && n) { //u[n] == 0 //debug:cout << "before n= " << n << endl; u[n] = cnt; //一开始数组u[n] = cnt == 0,!u[n]为真,持续循环 //之后cnt > 0,每次循环,u[n]被赋正值 //直到循环至n重复出现,即出现循环节,这时u[n]已经被赋值为正值,!u[n]为假,跳出循环 //debug:cout << "u[n]= " << cnt <<endl; remainder[cnt] = n; //记录余数 //debug:cout << "reamainder= " << n << endl; quotient[cnt++] = 10*n/m; //记录商 //debug:cout << "quotient= " << 10*n/m << endl; n = 10*n%m; //debug:cout << "after n= " << n << endl; //debug:cout << endl; } printf("%d/%d = %d.", t, m, quotient[0]); for (int i = 1 ; i < cnt && i <= 50 ; i++) { if (n && remainder[i] == n) printf("("); /*存在循环节->开始存在余数相同的位置*/ printf("%d",quotient[i]); } if (!n) printf("(0"); //余数为零 if (cnt > 50) printf("..."); printf(")\n"); printf(" %d = number of digits in repeating cycle\n\n",!n? 1:cnt-u[n]); } ForMyLove }
3-9 子序列(UVa 10340)
题意:给两个字符串A 和 B。 如果在B中能找到非连续字串和A匹配输出 YES 不能输出NO。
思路B一个个字母遍历过去每对应上A的一个字母就找A的下一个字母直到结束。。
#include <stdio.h> #include <string.h> char a[100005], b[100005]; int main() { while (~scanf("%s%s", a, b)) { int star = 0, lenb = strlen(b), lena = strlen(a); for (int i = 0; i < lenb; i ++) { if (a[star] == b[i]) star ++; if (star == lena) { printf("Yes\n"); break; } } if (star != lena) printf("No\n"); } return 0; }