《算法笔记》3.1小节——入门模拟->简单模拟
PAT B1001 害死人不偿命的(3n+1)猜想
#include <stdio.h>
int main() {
int n = 0, num = 0;
scanf("%d", &n);
while (n != 1) {
if (n % 2 == 0) n /= 2;
else n = (3*n + 1)/2;
num++;
}
printf("%d\n", num);
return 0;
}
PAT B1032 挖掘机技术哪家强
#include <stdio.h>
const int MAX = 100000;
int main() {
int N;
scanf("%d", &N);
int score[MAX] = { 0 };
int max=0,maxnum=0;
for(int i=0;i<N;i++) { //使用while (N--) ,会改变N的值,以后不能再用了
int id,scr;
scanf("%d %d", &id,&scr);
score[id] += scr;
}
for (int j = 1; j <= N; j++) { //题目计数从1开始,注意范围
if (max < score[j]) {
max = score[j];
maxnum = j;
}
}
printf("%d %d\n", maxnum, max);
return 0;
}
1814 Problem A 剩下的树
#include <stdio.h>
#include <string.h>
#include <algorithm> //swap()是在std::标准名词空间中的,来自algorithm
using namespace std;
const int MAX = 10000;
int main() {
int road[MAX],M, L, count=0;
while (scanf("%d %d",&L,&M)!=EOF) {
if (L == 0 && M == 0) break;
memset(road, 0, sizeof(road)); //要考虑每次循环前刷新;
count = 0;
while (M--) {
int low, high;
scanf("%d%d", &low, &high);
if (low > high) swap(low, high); //最好考虑low和high的大小,是否需要调换;
for (int i = low; i <= high; i++) {
road[i] = 1;
}
}
for (int i = 0; i <= L; i++) {
if (road[i] == 0) count++;
}
printf("%d\n", count);
}
return 0;
}
1817 Problem B A+B
sscanf很好用哦
#include <stdio.h>
#include <string.h>
void dispose(char a[]);
int main() {
char a[15], b[15];
int A, B;
while (scanf("%s %s", &a, &b) != EOF) {
//先出去字符串中的逗号;
dispose(a);
dispose(b);
int A, B;
//int sscanf( const char *buffer, const char *format, ... );
//sscanf函数从buffer(缓冲区)中读取
sscanf(a, "%d", &A);
sscanf(b, "%d", &B);
printf("%d\n", A + B);
//使用memset函数将数组重置
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
}
return 0;
}
void dispose(char a[]) {
char temp[15] = { 0 };
int pos = 0;
for (int i = 0; i < strlen(a);i++) {
if (a[i] != ',') temp[pos++] = a[i];
}
for (int i = 0; i < strlen(a); i++) {
a[i] = temp[i];
}
}
1906 Problem C 特殊乘法
#include <stdio.h>
#include <string.h>
int main() {
char a[10] = { '0' }, b[10] = { '0' };
while (scanf("%s %s", a, b) != EOF) { //对于数组,&a和a均可;
int sum = 0;
for (int i = 0; i < strlen(a); i++) {
for (int j = 0; j < strlen(b); j++) {
sum += (a[i] - '0') * (b[j] - '0');
//a[i]-'0'是两个字符的AscII码作差,差值代表char a[i]的int类型的值,此处一定要用'0'
}
}
printf("%d\n", sum);
memset(a, '0', sizeof(a));
memset(b, '0', sizeof(b));
//'\0'是转义字符,表示字符串结束, ASCII码为0,,'0'是数字字符0, ASCII码是48
//要在字符和整数之间转换,此处重新给ab字符串赋值为'\0'或'0',为避免出错可统一使用数字字符'0'
}
return 0;
}
另解,将整数转换为单个数字
#include <stdio.h>
#include <string.h>
int main() {
int A[10] = { '0' }, B[10] = { '0' };
int a = 0, b = 0;
while (scanf("%d %d", &a, &b) != EOF) { //读入整数
int sum = 0;
int alen, blen;
for (alen = 0; a != 0; alen++) { //整数转化为单个数字
A[alen] = a % 10;
a /= 10;
}
for (blen = 0; b != 0; blen++) {
B[blen] = b % 10;
b /= 10;
}
for (int i = 0; i < alen; i++)
for (int j = 0; j < blen; j++)
sum += A[i] * B[j];
printf("%d\n", sum);
}
return 0;
}
2036 Problem D 比较奇偶数个数
#include <stdio.h>
#include <string.h>
int main() {
int n;
while (scanf("%d", &n) != EOF) {
int a[1000] = { 0 }, even = 0, odd = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
if (a[i] % 2 == 0) even++;
else odd++;
//(a[i] % 2) ? (odd++) : (Even++);
}
if (even > odd) printf("NO\n");
else printf("YES\n");
//(even > odd) ? (printf("NO\n")) : (printf("YES\n"));
}
return 0;
}
6116 Problem E Shortest Distance (20)
查询的题目
静态查询:查询的结果在输入结束时已经得出,或者经过简易的计算就可以得出
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int main() {
int N, D[10000] = { 0 },sum=0;
scanf("%d", &N);
for (int i = 1; i <= N; i++) {
scanf("%d", &D[i]);
sum += D[i];
}
int M = 0;
scanf("%d", &M);
while (M--) {
int low = 0, high = 0, dis1 = 0, dis2 = 0;
scanf("%d %d", &low, &high);
if (low > high) swap(low, high);
for (int i = low; i < high; i++) {
dis1 += D[i];
}
dis2 = sum - dis1;
if (dis2 < dis1) printf("%d\n", dis2);
else printf("%d\n", dis1);
//(dis2 < dis1) ? printf("%d\n", dis2) : printf("%d\n", dis1);
}
return 0;
}
动态查询:根据查询的内容再开始计算,在之前并没有对数据进行处理。在查询数目很多时,很容易超时。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int main() {
int N, D[100000] = { 0 },sum=0;
int distance[100000] = { 0 };
scanf("%d", &N);
for (int i = 1; i <= N; i++) {
scanf("%d", &D[i]);
sum += D[i];
distance[i + 1] = distance[i] + D[i];
}
int M = 0;
scanf("%d", &M);
while (M--) {
int low = 0, high = 0, dis1 = 0, dis2 = 0;
scanf("%d %d", &low, &high);
if (low > high) swap(low, high);
dis1 = distance[high] - distance[low];
dis2 = sum - dis1;
if (dis2 < dis1) printf("%d\n", dis2);
else printf("%d\n", dis1);
//(dis2 < dis1) ? printf("%d\n", dis2) : printf("%d\n", dis1);
}
return 0;
}
出现查询的题目,首先想到的应该是尽量减少从查询输入到输出结果之间的处理时间。
6128 Problem F A+B和C (15)
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
for(int i=0;i<T;i++)
{
long long a = 0, b = 0, c = 0;
scanf("%d%d%d", &a, &b, &c);
(a + b) > c ? printf("Case #%lld: true\n", i+1) : printf("Case #%lld: false\n", i+1);
//注意区间[-2^31,2^31]之间的数字用long long类型
}
return 0;
}
6129 Problem G 数字分类 (20)
#include <stdio.h>
#include <string.h>
int main() {
int N;
while (scanf("%d", &N) != EOF) {
int a[1000] = { 0 }, count[5] = { 0 };
//用count数组记录每种情况的数字,或使用flag判断有无某类数字;
int A[5] = { 0 };
for (int i = 0; i < N; i++) {
scanf("%d", &a[i]);
}
for (int i = 0; i < N; i++) {
switch (a[i] % 5) {
case 0:
if (a[i] % 2 == 0) {
A[0] += a[i];
count[0]++;
} //注意什么时候count++;
break;
case 1:
if (count[1] % 2 == 0) A[1] += a[i];
else A[1] -= a[i];
count[1]++;
break;
case 2:
A[2]++; count[2]++;
break;
case 3:
A[3] += a[i]; count[3]++; //还需相除;
break;
case 4:
if (A[4] < a[i]) A[4] = a[i];
count[4]++;
break;
}
//使用switch要每个case后加break,否则会逐一运行
}
for (int i = 0; i < 5; i++) {
if (i == 3) count[i] == 0 ? printf("N") : printf("%.1f", (A[i] * 1.0 / count[i]));
else count[i] == 0 ? printf("N") : printf("%d", A[i]);
if (i == 4) printf("\n");
else printf(" ");
}
}
return 0;
}
6170 Problem H 部分A+B (15)
方法一:对数字按位处理
#include <stdio.h>
#include <string.h>
int main() {
int a, DA, b, DB;
while (scanf("%d%d%d%d", &a, &DA, &b, &DB) != EOF) {
int PA = 0, PB = 0;
int A[10] = { 0 }, B[1] = { 0 };
for (int i = 0; a != 0; i++) {
A[i] = a % 10; a /= 10;
if (A[i] == DA) PA = PA * 10 + DA;
}
for (int i = 0; b != 0; i++) {
B[i] = b % 10; b /= 10;
if (B[i] == DB) PB = PB * 10 + DB;
}
printf("%d\n", PA + PB);
}
return 0;
}
方法二:按照字符串 字符输入和处理,用sscanf转换为整数输出
#include <stdio.h>
#include <string.h>
int trans(char a[], char DA);
int main() {
char a[10] = { 0 }, DA, b[10] = { 0 } , DB;
while (scanf("%s %c %s %c", &a, &DA, &b, &DB) != EOF) {
int PA = 0, PB = 0;
PA = trans(a, DA);
PB = trans(b, DB);
printf("%d\n", PA + PB);
}
return 0;
}
int trans(char a[], char DA) {
int PA = 0;
int num = 0;
for (int i = 0; a[i] != '\0'; i++) {
if (a[i] == DA) num++;
}
for (int i = 0; i < num; i++) {
a[i] = DA;
}
a[num] = '\0';
sscanf(a, "%d", &PA);
return PA;
}
6172 Problem I 锤子剪刀布 (20)
#include <stdio.h>
#include <string.h>
int main() {
int A[3] = { 0 }, B[3] = { 0 }, P=0;
int maxa = 0, maxb = 0;
int N;
scanf("%d\n", &N);
//如果用scanf("%d", &N);的话,后面要加getchar();
//在指定完个数后,如果你要输入的是字符,一定要加上一句"getchar();",少了这句会把回车都存进去从而导致错误
//如果你要输入的是数字,则不用加入这句。
while (N--) {
char a, b;
scanf("%c %c ", &a, &b);
//读入字符时两个字符之间的空格要额外吸收掉,否则将会把空格读入。可采用%*c实现
if (a == 'B') {
switch (b) {
case 'B':P++; break;
case 'C':A[0]++; break;
case 'J':B[2]++; break;
}
}
else if (a == 'C') {
switch (b) {
case 'B':B[0]++; break;
case 'C':P++; break;
case 'J':A[1]++; break;
}
}
else if (a == 'J') {
switch (b) {
case 'B':A[2]++; break;
case 'C':B[1]++; break;
case 'J':P++; break;
}
}
}
printf("%d %d %d\n", A[0] + A[1] + A[2], P, B[0] + B[1] + B[2]);
printf("%d %d %d\n", B[0] + B[1] + B[2], P, A[0] + A[1] + A[2]);
maxa = A[0]; maxb = B[0];
char sa='B', sb='B';
if (maxa < A[1]) {
maxa = A[1]; sa = 'C';
}
if (maxa < A[2]) {
maxa = A[2]; sa = 'J';
}
if (maxb < B[1]) {
maxb = B[1]; sa = 'C';
}
if (maxb < B[2]) {
maxb = B[2]; sa = 'J';
}
printf("%c %c\n", sa, sb);
}
PAT上测试点3过不去,没找到原因