《算法笔记》3.1小节——入门模拟->简单模拟

问题 A: 剩下的树

题目描述
有一个长度为整数L(1<=L<=10000)的马路,可以想象成数轴上长度为L的一个线段,起点是坐标原点,在每个整数坐标点有一棵树,即在0,1,2,…,L共L+1个位置上有L+1棵树。
现在要移走一些树,移走的树的区间用一对数字表示,如 100 200表示移走从100到200之间(包括端点)所有的树。
可能有M(1<=M<=100)个区间,区间之间可能有重叠。现在要求移走所有区间的树之后剩下的树的个数。

输入
两个整数L(1<=L<=10000)和M(1<=M<=100)。
接下来有M组整数,每组有一对数字。

输出
可能有多组输入数据,对于每组输入数据,输出一个数,表示移走所有区间的树之后剩下的树的个数。

***样例输入 ***
4 2
1 2
0 2
11 2
1 5
4 7
0 0
***样例输出 ***
2
5
参考代码

#include 
int main(){
    int n,m,x,y,maxs,mins,a,rest;
    scanf("%d %d",&n,&m);
    while(n != 0 && m != 0){
        int arr[2*m];
        int j = 0;
        for(int i = 0; i < m; i ++){
            scanf("%d %d",&x,&y);
            arr[j] = x;
            j ++;
            arr[j] = y;
            j ++;
        }

        maxs = arr[0];
        mins = arr[0];
        for(int i = 1;i < 2*m;i ++){
            if(maxs <= arr[i]){
                maxs = arr[i];
            }
        }
        for(int i = 0;i < 2*m;i ++){
            if(mins >= arr[i]){
                mins = arr[i];
            }
        }
        a = maxs - mins + 1;

        rest = (n + 1) - a;

        printf("%d\n",rest);

        scanf("%d %d",&n,&m);

    }
    return 0;
}

问题 B: A+B

题目描述
给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号","隔开。
现在请计算A+B的结果,并以正常形式输出。

输入
输入包含多组数据数据,每组数据占一行,由两个整数A和B组成(-10^9 < A,B < 10^9)。

输出
请计算A+B的结果,并以正常形式输出,每组数据占一行。

***样例输入 ***
-234,567,890 123,456,789
1,234 2,345,678
***样例输出 ***
-111111101
2346912
参考代码

#include 
#include 
#include 

int getint(char s[])
{
   int digital=1,length;
   int result=0;
   length=strlen(s);
   for(int i=length-1;i>=0;i--)
   {
       if(s[i]>='0'&&s[i]<='9')
       {
           result=result+(s[i]-48)*digital;
           digital=digital*10;
       }
       if(s[i]=='-')
        result=result*(-1);
       else
        continue;
   }
   return result;
}
int main()
{
	char A[20], B[20];
	int a, b;

	while (scanf("%s %s", &A, &B) != EOF)
	{
		a = getint(A);
		b = getint(B);
		printf("%d\n", a + b);
	}
}

问题 C: 特殊乘法

题目描述
写个算法,对2个小于1000000000的输入,求结果。特殊乘法举例:123 * 45 = 14 +15 +24 +25 +34+35
输入
两个小于1000000000的数

输出
输入可能有多组数据,对于每一组数据,输出Input中的两个数按照题目要求的方法进行运算后得到的结果。

样例输入
24 65
42 66666
3 67
样例输出
66
180
39
参考代码

#include 
#include 
#include
int main()
{
    char a[10]={'\0'},b[10]={'\0'};
    int i,j,s0,s1,s;
    while(~scanf("%s%s",a,b))
    {
        s0=0;
        s1=0;
        s=0;
        for(i=0;i<strlen(a);i++)
            s0=s0+a[i]-'0';
        for(i=0;i<strlen(b);i++)
            s1=s1+b[i]-'0';
        s=s0*s1;

        printf("%d\n",s);
    }
    return 0;
}

问题 D: 比较奇偶数个数

题目描述
第一行输入一个数,为n,第二行输入n个数,这n个数中,如果偶数比奇数多,输出NO,否则输出YES。

输入

输入有多组数据。
每组输入n,然后输入n个整数(1<=n<=1000)。

输出

如果偶数比奇数多,输出NO,否则输出YES。

样例输入
1
67
7
0 69 24 78 58 62 64
样例输出
YES
NO
参考代码

#include 
#include 

int main()
{
    int n,a,p,q;
    while(~scanf("%d",&n))
    {
        p=0;q=0;
        while(n--)
        {
            scanf("%d",&a);
            if(a%2==0)
                p++;
            else
                q++;
        }
        if(p>=q)
            printf("NO\n");
        else
            printf("YES\n");
    }
    return 0;
}

问题 F: A+B和C (15)

题目描述
给定区间[-231, 231]内的3个整数A、B和C,请判断A+B是否大于C。
输入
输入第1行给出正整数T(<=10),是测试用例的个数。随后给出T组测试用例,每组占一行,顺序给出A、B和C。整数间以空格分隔。
输出
对每组测试用例,在一行中输出“Case #X: true”如果A+B>C,否则输出“Case #X: false”,其中X是测试用例的编号(从1开始)。
样例输入
4
1 2 3
2 3 4
2147483647 0 2147483646
0 -2147483648 -2147483647
样例输出
Case #1: false
Case #2: true
Case #3: true
Case #4: false
参考代码

#include 
#include 

int main()
{
    int T,t,i;
    long int a,b,c;
   scanf("%d",&T);

        t=T;
        while(T--)
        {
            i=t-T;
            scanf("%ld%ld%ld",&a,&b,&c);
            if(a+b<=c)
                printf("Case #%d: false\n",i);
            else
                printf("Case #%d: true\n",i);
        }


    return 0;
}

问题 G: 数字分类 (20)

题目描述
给定一系列正整数,请按要求对数字进行分类,并输出以下5个数字:

A1 = 能被5整除的数字中所有偶数的和;
A2 = 将被5除后余1的数字按给出顺序进行交错求和,即计算n1-n2+n3-n4…;
A3 = 被5除后余2的数字的个数;
A4 = 被5除后余3的数字的平均数,精确到小数点后1位;
A5 = 被5除后余4的数字中最大数字。
输入
每个输入包含1个测试用例。每个测试用例先给出一个不超过1000的正整数N,随后给出N个不超过1000的待分类的正整数。数字间以空格分隔。
输出
对给定的N个正整数,按题目要求计算A1~A5并在一行中顺序输出。数字间以空格分隔,但行末不得有多余空格。

若其中某一类数字不存在,则在相应位置输出“N”。

样例输入
13 1 2 3 4 5 6 7 8 9 10 20 16 18
8 1 2 4 5 6 7 9 16
样例输出
30 11 2 9.7 9
N 11 2 N 9
参考代码(拷贝网友的c++代码)

#include 
#include 
using namespace std;
int main() {
     int n, num, A1 = 0, A2 = 0, A5 = 0;
  double A4 = 0.0;
     cin >> n;
     vector<int> v[5];
     for (int i = 0; i < n; i++) {
     cin >> num;
     v[num%5].push_back(num);
    }
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < v[i].size(); j++) {
        if (i == 0 && v[i][j] % 2 == 0) A1 += v[i][j];
        if (i == 1 && j % 2 == 0) A2 += v[i][j];
        if (i == 1 && j % 2 == 1) A2 -= v[i][j];
        if (i == 3) A4 += v[i][j];
       if (i == 4 && v[i][j] > A5) A5 = v[i][j];
        }
    }
    for (int i = 0; i < 5; i++) {
        if (i != 0) printf(" ");
        if (i == 0 && A1 == 0 || i != 0 && v[i].size() == 0) {
            printf("N"); continue;
        }
         if (i == 0) printf("%d", A1);
        if (i == 1) printf("%d", A2);
        if (i == 2) printf("%d", v[2].size());
        if (i == 3) printf("%.1f", A4 / v[3].size());
        if (i == 4) printf("%d", A5);
     }
     return 0;
}

问题 H: 部分A+B (15)

题目描述
正整数A的“DA(为1位整数)部分”定义为由A中所有DA组成的新整数PA。例如:给定A = 3862767,DA = 6,则A的“6部分”PA是66,因为A中有2个6。

现给定A、DA、B、DB,请编写程序计算PA + PB。

输入
输入在一行中依次给出A、DA、B、DB,中间以空格分隔,其中0 < A, B < 1010。
输出
在一行中输出PA + PB的值。
样例输入
3862767 6 13530293 3
3862767 1 13530293 8
样例输出
399
0
参考代码

#include
int main()
{
    int A,DA,PA;
    int B,DB,PB;
   // while(!0)
   // {
        PA=PB=0;
        scanf("%d%d%d%d",&A,&DA,&B,&DB);
        while(A!=0)
        {
            if(A%10==DA)
            {
                PA=PA*10+DA;
            }
            A=A/10;
        }
        while(B!=0)
        {
            if(B%10==DB)
            {
                PB=PB*10+DB;
            }
            B=B/10;
        }
        printf("%d\n",PA+PB);
   // }
    return 0;
}

问题 I: 锤子剪刀布 (20)

题目描述
大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示:
《算法笔记》3.1小节——入门模拟->简单模拟_第1张图片

现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。

输入
输入第1行给出正整数N(<=105),即双方交锋的次数。随后N行,每行给出一次交锋的信息,即甲、乙双方同时给出的的手势。C代表“锤子”、J代表“剪刀”、B代表“布”,第1个字母代表甲方,第2个代表乙方,中间有1个空格。
输出
输出第1、2行分别给出甲、乙的胜、平、负次数,数字间以1个空格分隔。第3行给出两个字母,分别代表甲、乙获胜次数最多的手势,中间有1个空格。如果解不唯一,则输出按字母序最小的解。
样例输入
10
C J
J B
C B
B B
B C
C C
C B
J B
B C
J J
样例输出
5 3 2
2 3 5
B B
参考代码(拷贝的网友的代码)

#include
using namespace std;
int main()
{
	char MaxNum(int a, int b, int c);
	long count = 0;
	cin >> count;
	long arrAwin[3] = { 0 };
	long countNumA[3] = { 0 };//B C J
	long countNumB[3] = { 0 };//B C J
	for (size_t i = 0; i < count; i++)
	{
		char A;
		char B;
		cin >> A;
		cin >> B;
		if ((A == 'C' && B == 'J') || (A == 'J' && B == 'B') || (A == 'B' && B == 'C'))
		{
			arrAwin[0]++;
			if (A == 'B')
			{
				countNumA[0]++;
			}
			if (A == 'C')
			{
				countNumA[1]++;
			}
			if (A == 'J')
			{
				countNumA[2]++;
			}
		}
		//if ((A == 'C'&&B == 'C') || (A == 'J'&&B == 'J') || (A == 'B'&&B == 'B'))
		if (A == B)
		{
			arrAwin[1]++;
		}
		if ((A == 'J' && B == 'C') || (A == 'B' && B == 'J') || (A == 'C' && B == 'B'))
		{
			arrAwin[2]++;
			if (B == 'B')
			{
				countNumB[0]++;
			}
			if (B == 'C')
			{
				countNumB[1]++;
			}
			if (B == 'J')
			{
				countNumB[2]++;
			}
		}

	}
	cout << arrAwin[0] << " " << arrAwin[1] << " " << arrAwin[2] << endl;
	cout << arrAwin[2] << " " << arrAwin[1] << " " << arrAwin[0] << endl;
	cout << MaxNum(countNumA[0], countNumA[1], countNumA[2]) << " " << MaxNum(countNumB[0], countNumB[1], countNumB[2]) << endl;
	return 0;

}
char MaxNum(int a, int b, int c)
{
	if (a >= b && a >= c)
	{
		return 'B';
	}
	if (b >= a && b >= c)
	{
		return 'C';
	}
	if (c >= a && c >= b)
	{
		return 'J';
	}
}

你可能感兴趣的:(算法笔记练习,数据结构)