qlu_新生赛_2018_代码汇总

https://blog.csdn.net/weixin_43537190/article/details/84570246
记得看看梁延杰的blog 可能会有小惊喜
还有就是别的学校的新生题
本文章全都是转载,只为个人日后方便复习

  • 1 输入3个字符串,按字典序从小到大进行排序。
    就是a b c三个数,第一位置和第二位置比完之后,第一位置大于第二位置,然后第二位置和第三位置相比,第二位置大于第三位置,但是现在不知道第一位置和第二位置的大小了,所以还得在比较一下第一位置和第二位置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<stdio.h>
#include<string.h>
int main()
{
	char a[100],b[100],c[100],d[100];
	scanf("%s%s%s",a,b,c);
    //下面的abc其实就代表了第一个位置,第二个位置,第三个位置
	if(strcmp(a,b)>0)//若a>b 将a值换成b的 实际还是a 
    {
        strcpy(d,a);
        strcpy(a,b);
        strcpy(b,d);
    }
    if(strcmp(b,c)>0)//b与c比较 若上一步改变 则是a与c的比较 
    {
        strcpy(d,b);
        strcpy(b,c);
        strcpy(c,d);
    }
    if(strcmp(a,b)>0)//a与b比较 此时的a与b值发生变化  结果为b与c或者a与c比较 
    {
        strcpy(d,a);
        strcpy(a,b);
        strcpy(b,d);
    }
    printf("%s %s %s",a,b,c);
    return 0;
}

上面加了注释 因为第一次做的时候只想着用a b c的比较来输出最终的结果 忘记了复制
交换的过程中a b c字符串已经换了数据 所以要想都比较一遍必须按上面的 步骤 比较方法来!!!千万要注意
  • 2 问题 M: 签到题
    题目描述
    恭喜你发现一道签到题,请输出“check in”来解决这道问题。
    输入

    输出
    check in
    样例输入

    样例输出
    check in
1
2
3
4
5
#include<bits/stdc++.h>
using namespace std;
int main() {
	cout<<"check in";
}
  • 3问题 B: Alice and Bob
    命题人:admin
    题目描述
    Alice and Bob decide to play a game. At the beginning of the game they put n piles of sweets on the table.The number of each pile of sweets may be different. Alice and Bob take away sweets in turn,and always Alice takes sweets first in every games.Each time in their turn they can get only one whole pile of sweets.When there is no sweet left, the game is over. Finally, The man who have the largest number of sweets in hand will win.
    Assume that Alice and Bob were very clever.
    输入
    The first line is an integer n, which means that there are n pile sweets.
    1 <= n <= 100000
    Next n integers, the i-th integer means the number of sweets in the i-th pile.
    The number of sweets in each pile is less than 10000.
    输出
    If Alice wins, output “A”, and if Bob wins, output “B”.
    Otherwise output “again”
    样例输入
    样例输入1:
    3
    1 6 7
    样例输入2:
    4
    3 3 3 3
    题目大意为桌子上有很多堆糖果,每一堆糖果的数量可能不相同,这个Alice姐姐和Bob玩一个游戏 每个人一次拿一堆,比较最后谁拿到的糖果比较多。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include<bits/stdc++.h>
using namespace std;
int b=0,c=0;
unsigned long long int a[200000];
bool cmp(int a,int b) {
	return a>b;     //定义从大到小排列的算子
}
int main() {
	long long int  n; //long long表示1e18;int 最大表示1e8
	cin>>n;
	for(int i=1;i<=n;i++) {
		cin>>a[i];
	}
	sort(a+1,a+n+1,cmp);    //因为他们都很聪明这句话,说明要从大到小排序
    //因为i是从1开始的,所以sort要这么写才可以
	for(int i=1;i<=n;i++) {
	if(n==1) {
		if(a[n]<=0)
		cout<<"again";    //对n==1这种特殊情况讨论
		else if(a[n]>0)
		cout<<"A";
		return 0;
	}
	else if(n>1&&(i%2!=0))  //如果i%2!=0就代表alice取糖果
	b+=a[i];
	else if(n>1&&(i%2==0))
	c+=a[i];
	}
	if(b>c)
	cout<<"A";
	else if(b<c)
	cout<<"B";
	else if(b==c)
	cout<<"again";

} 

方法二:其实一想bob根本没有赢得机会,只要判断是否是平局就好了
#include <stdio.h>
int main()
{
	int n;
	int A=0,B=0;
	int temp;
	int a[100001];
	scanf("%d",&n);		//没说输入数据有多组,就当只有一组处理就好了
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
	{
		if(i%2!=0)
		A=A+a[i];
		else if(i%2==0)
		B=B+a[i];
	}
	if(A==B)
		printf("again");
	else
		printf("A"); 
	return 0;
}

方法三:
#include<bits/stdc++.h>
using namespace std;
int n;
int a[10005];
int main()
{
    scanf("%d",&n);
    int k;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&k);
        a[k]++;//我这里使用的桶来记录是否均分(均分就是alice和bob得到的糖果一样多)
        //数组a就相当于一个桶,这个桶记录了一堆糖果的个数的出现的次数;
        //如果桶全是偶数次就是均分,存在一个奇数次就不是均分
    }
 
    if(n&1)//奇数堆,相当于n%2
    {
        printf("A\n");
        return 0;
    }
    else//偶数堆
    {
        for(int i=1;i<=1000;i++)
        {
            if(a[i]&1)//存在奇数桶,不均分
            {
                printf("A\n");
                return 0;
            }
        }
        printf("again\n");//均分
    }
}
  • 4 问题 C: 黑白黑
    命题人:admin
    题目描述
    黑白黑是一个很经典的游戏,规则也非常简单。三个人同时伸出一只手,手心为白,手背为黑,如果有两人为黑一人为白,或者两人为白一人为黑,则单独伸出手心或者手背的那个人就输了。
    又是一个周末,小A小B小C他们仨个懒虫又睡到了中午,外卖送到楼下了也不想下楼拿,于是他们决定用这个游戏来选出一个输的人去拿外卖。

输入
三个整数
a b c
(0 <= a,b,c <= 1)
a表示小A
b表示小B
c表示小C
0表示伸出的手背
1表示伸出的手心
输出
如果有人输了则输出他的名字A/B/C(大写)
平局则输出”aha”(不含引号)
样例输入
样例输入1:
0 0 0
样例输入2:
1 1 0
样例输出
样例输出1:
aha
样例输出2:
C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
所有的情况不多,挨个枚举:
#include<bits/stdc++.h>
using namespace std;
int main() {
	int a,b,c;
	cin>>a>>b>>c;
	if((a==0&&b==0&&c==0)||(a==1&&b==1&&c==1))
	cout<<"aha";
	else if((a==1&&b==1&&c==0)||(a==0&&b==0&&c==1))
	cout<<"C";
	else if((a==1&&b==0&&c==1)||(a==0&&b==1&&c==0))
	cout<<"B";
	else if((a==0&&b==1&&c==1)||(a==1&&b==0&&c==0))
	cout<<"A";
} 

方法二(只需要判断 是不是两个相同的和一个不同的即可):
#include <bits/stdc++.h>
using namespace std;
int a, b, c;
int main()
{
    cin >> a >> b >> c;
    if (a == b && b == c)
        cout << "aha";
    else if (a == b)
        cout << "C";
    else if (b == c)
        cout << "A";
    else if (a == c)
        cout << "B";
    return 0;
}
  • 5问题 E: are you ok?
    题目描述
    小朋是一家超市的老板,他经常会来超市检查,每次都会让仓库管理员列出仓库中剩余商品的数量。但是仓库管理员是个非常健忘的人,有时候商品都卖光了也不去进货,这会让老板非常生气,因为这样超市卖不出去东西就没办法赚钱了。小朋有句口头禅”are you ok?”,如果发现所有商品的库存都为0的话,就会非常生气地喊出”are you ok?”,大声地质询仓库管理员。
    现在你就是仓库管理员,每次面对小朋的询问,你都会在电脑系统中对库存进行查询,然后列出剩余商品的清单。(如果所有商品库存都是0,那你就没办法交差了,你的老板会非常生气)。
    输入
    第一行一个整数n,表示有n种货物
    (2 <= n <= 100)
    往下一行有n个字符串s1,s2…si…sn 表示系统显示的第i种货物的名称(1<=i<=n)
    (字符串长度不超过10)
    往下一行有n个整数a1,a2…ai…an 表示系统显示的第i种货物的库存(1<=i<=n)
    (每种货物库存数量 <= 1000)
    输出
    如果还有商品(哪怕只有一个),你也可以列出剩余商品的清单。
    否则你就只能挨老板骂了。
    样例输入
    样例输入1:
    4
    a b c d
    0 0 0 0

    样例输入2:
    5
    apple egg milk desk light
    0 1 2 0 1

    样例输出
    样例输出1:
    are you ok?

    样例1的说明:
    所有的商品都没库存, 你的老板会非常生气

    样例输出2:
    egg x 1
    milk x 2
    light x 1
    (x前后有空格)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<bits/stdc++.h>
using namespace std;
int f=0;
struct node {
	string name;
	int num;
}a[2000];
int main() {
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	cin>>a[i].name;
	for(int i=0;i<n;i++)
	cin>>a[i].num;
	for(int i=0;i<n;i++) {
		if(a[i].num!=0) {
			cout<<a[i].name<<" x "<<a[i].num<<"\n";
			f=1;
		}
	}
	if(f==0)
	cout<<"are you ok?";
}
  • 6 问题 G: 数数
    题目描述
    小凯今年上一年级了,他只学会了0-9这十个数字,对于两位以上的数字,小凯自创了一套读法。
    连续出现的x个y,小凯将其读作“xy”
    比如:11 小凯读作”21” (连续2个1)
    21 小凯读作”1211” (连续1个2 连续1个1)
    99 小凯读作”29” (连续2个9)
    310 小凯读作”131110”(连续1个3 连续1个1 连续1个0)
    330111 小凯读作”231031”(连续2个3 连续1个0 连续3个1)
    给定一个由数字组成的字符串n(2 <= |n| <= 100),请输出小凯对n的读法
    |n|表示字符串n的长度
    保证连续出现同一个数字的次数不会超过9次(因为小凯最多只能数到9)
    比如:2223311111111118(非法,因为数字1连续出现了10次)

输入
由纯数字组成的一行字符串

输出
在小凯的自创规则下这一长串数的读法

样例输入
13145

样例输出
1113111415

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
这种的输出3a4b形式的可以用这种方法来解题,而不是用那种拼接字符串的形式
#include<bits/stdc++.h>
using namespace std;
int main() {
	string a;
	cin>>a;
	int sum=1;
	for(int i=0;i<a.size();i++) {
		if(a[i]==a[i+1])	//当为a[a.size()]的时候输出'\0'
			sum++;
		else {
			cout<<sum<<a[i];
			sum=1;
		}
	}
}

方法二:
#include<bits/stdc++.h>
using namespace std;
string s;
int Count=0;
 
int main()
{
    cin>>s;
    Count=1;//第一个数字的
    for(int i=1;i<s.length();i++)
    {
        if(s[i]==s[i-1])//前后相同
        {
            Count++;
        }
        else//前后不同了 重新开始
        {
            cout<<Count<<s[i-1];
            Count=1;
        }
        if(i==s.length()-1&&Count) 
        {//特判,如果全是一个数字,因为这个是下标为i和i-1的相比,当i为最后一个
        //的时候会执行count++语句,而不是输出count语句
            cout<<Count<<s[i];
        }
    }
}
  • 7问题 H: 神奇老虎机
    不知道你有没有玩过老虎机,现在小明面前有一台神奇的老虎机,这台机器有n个滚轮,从左往右数第i个滚轮包含1到a_i的整数(包括1和a_i)。在按下按钮之后,所有的滚轮都会飞速旋转,最终停下来,每个滚轮将显示其中一个整数。这个过程是随机的。小明有一个有趣的想法,如果将滚轮显示的数字连接起来看做一长串字符串的话,将会有非常多的可能,在这所有的可能中字典序最小的字符串是哪个?(只能从左向右读)

对于字典序的说明:
两个字符串S和T,从前往后比较,如果存在一个位置,在该位置两个字符串的字符不同,则比较小的那个所在的字符串字典序更小。
例如: 123的字典序比14的小,因为在第二个位置上2小于4
12345的字典序比9的小
220的字典序比22的大,因为22是220的一个前缀

输入
一个整数t,表示有t组数据(1 <= t <= 100)
每组第一行为一个整数n表示老虎机有n个滚轮
(1 <= n <= 1000)
第二行为n个整数(a_1 a_2 … a_i … a_n )
表示第i个滚轮上的数字范围(1~a_i)
(1 <= a_i <= 100)

输出
每组输入对应一行输出,输出字典序最小时老虎机滚轮上显示的数字
两个数字之间用空格隔开

样例输入
2
4
6 6 6 6
2
2 2

样例输出
1 1 1 1
1 1

提示
老虎机上显示的数都不含前导0
比如:某一块滚轮包含[1,33],如果它显示”1”的话,显示的是”1”而不是”01”

对于样例2的解释:
所有情况分别为:“1 1”、“1 2”、“2 1”、“2 2”
其中”1 1”是字典序最小的,所以答案为”1 1”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<bits/stdc++.h>
using namespace std;
int main() {
	int t,n,x;
	cin>>t;
	for(int i=0;i<t;i++) {
		cin>>n;
		for(int j=0;j<n-1;j++) {
			cin>>x;
			if(x<10)
			cout<<1<<" ";
			if(x>=10&&x<100)
			cout<<10<<" ";
			if(x==100)
			cout<<100<<" ";
		}
		cin>>x;
		cout<<1<<" \n";
	} 
}
有个疑问:为什么最后要输出1呐,因为最后一个数的前缀只有是1的时候才最小
1是10或者100的前缀
  • 8问题 I: 五环
    题目描述
    提到五环,我想大家都非常熟悉。 “啊五环你比四环多一环~~”
    不好意思 跑题了。。。
    奥运五环由蓝、黄、黑、绿、红五种颜色的圆环组成。
    小迪认为五个圆环分别代表五大洲:
    蓝色 = 欧洲
    黄色 = 亚洲
    黑色 = 非洲
    绿色 = 大洋州
    红色 = 美洲
    对应英文为
    Blue = Europe
    Yellow = Asia
    Black = Africa
    Green = Oceania
    Red = America

    输入
    输入一行字符串
    字符串为五环的颜色或者五个大洲的名称

    输出
    如果输入的是颜色则输出对应的大洲
    如果输入的是大洲则输出对应的颜色

    样例输入
    Blue

    样例输出
    Europe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
方法一(map集合):
#include<bits/stdc++.h>
using namespace std;
map<string,string>a;
int main() {
	a["Blue"]="Europe";
	a["Yellow"]="Asia";
	a["Black"]="Africa";
	a["Green"]="Oceania";
	a["Red"]="America";
	a["Europe"]="Blue";
	a["Asia"]="Yellow";
	a["Africa"]="Black";
	a["Oceania"]="Green";
	a["America"]="Red";
	string b;
	cin>>b;
	cout<<a[b];
}

方法二:
#include<bits/stdc++.h>
using namespace std;
int main() {
	string a;
	cin>>a;
	if(a=="Blue")
	cout<<"Europe";
	else if(a=="Yellow")
	cout<<"Asia";
	else if(a=="Black")
	cout<<"Africa";
	else if(a=="Green")
	cout<<"Oceania";
	else if(a=="Red")
	cout<<"America";
	else if(a=="Europe")
	cout<<"Blue";
	else if(a=="Asia")
	cout<<"Yellow";
	else if(a=="Africa")
	cout<<"Black";
	else if(a=="Oceania")
	cout<<"Green";
	else if(a=="America")
	cout<<"Red";
}
  • 9 问题 J: 开挂的小洋
    命题人:admin
    题目描述
    最近小洋迷上了一款名叫打地鼠的游戏,但是小洋是个游戏白痴,这么简单的游戏也总是得不到几分,有一天他发现这款游戏可以在网络上买到外挂,这款外挂可以提前预知所有地鼠出现的时间,并且他可以开局得到两把锤子,之前小洋1s只能挥动一次锤子,现在他左右开弓可以同时打中最多两只地鼠。每只地鼠在第i秒出现,在第i+1秒的时候就会消失。也就是说在第i秒小洋只能打到这一秒出现的地鼠,(i-1)秒以及(i+1)秒出现的地鼠他都没办法打中。

    输入
    一个整数n,表示地鼠的数目
    一个整数m,表示此次游戏时长
    接下来n个整数a_1-a_n,表示地鼠会在第a_i秒出现
    1 <= a_i <= m
    1 <= n <= 1000;
    1 <= m <= 100000;
    每只地鼠最多停留一秒

    输出
    一个整数,表示小洋最高得分(每打中一只地鼠得一分)

    样例输入
    样例输入1:
    4
    9
    1 1 4 7

    样例输入2:
    6
    10
    3 3 3 3 9 1

    样例输出
    样例输出1:
    4

    样例输出2:
    4

    提示
    对于样例1的解释:
    第1秒出现两只地鼠 左右开弓两只全打中得2分
    第4秒出现一只地鼠 打中得1分
    第7秒出现一只地鼠 打中得1分
    最终得分4分

    对于样例2的解释:
    第1秒出现一只地鼠 打中得1分
    第3秒出现四只地鼠 两把锤子最多打中两只 得2分
    第9秒出现一只地鼠 打中得1分
    共4分

其实本题就是一个时间段内求不同位置的出现次数的个数问题,但同一时间出现大于两次的情况算两次,这就可以通过把不同位置当做数组的下标,然后通过数组的大小判断出现次数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<bits/stdc++.h>
using namespace std;
int a[200000];
int main() {
	int n,m,count=0,b;
	cin>>n>>m;
	for(int i=0;i<n;i++) {
		cin>>b;
		a[b]++;
	}
	for(int i=0;i<200000;i++) {
		if(a[i]!=0) {
			if(a[i]>=2)    //因为同一时间出现2个以上的仓鼠,只能打死其中两个
			count+=2;
			if(a[i]==1)
			count+=1;
		}
	}
	cout<<count;
}
  • 10 问题 K: 数字匹配
    题目描述
    给出两个元素数量都为n的数组a和数组b。对于数组a中的每个元素,都必须找一个(而且最多一个)数组b中的元素进行匹配,数组b中的所有元素也都要被匹配到,也就是说一一匹配。匹配完成后,相互匹配的元素相乘,然后把所有的积相加。
    例如:
    数组a:1 5 3
    数组 b:2 3 4
    如果a中第一个元素跟b中第三个元素匹配,第二个元素跟b中第二个元素匹配,第三个元素跟b中第一个元素匹配,匹配完后相乘得到 14、53、32,求和得到结果14+53+32=25。
    如果a中第一个元素跟b中第二个元素匹配,第二个元素跟b中第三个元素匹配,第三个元素跟b中第一个元素匹配,匹配完后相乘得到 13、54、32,求和得到结果13+54+32=29。

给出n和两个数组,分别计算求和的最大结果与最小结果。

输入
第一行 一个数n,表示两个数组元素的个数 1<=n<=1000。
第二行 n个数 表示数组a的各个元素ai,0<ai<=1000 ai为正整数,(1<=i<=n)。
第三行 n个数 表示数组b的各个元素bi,0<bi<=1000 bi为正整数,(1<=i<=n)。

输出
两个数 分别表示最大结果和最小结果。最大结果和最小结果可以相等。

样例输入
3
1 5 3
2 3 4

样例输出
31 23

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
首先这一题可以不通过全部都遍历一遍(对a数组求next_pretutation(),数组a和数组b相乘)就可以求出结果;可以通过a的降序和b的降序1对1,2对
#include<bits/stdc++.h>
using namespace std;
int n,a[2000],b[2000];
bool cmp(int a,int b) {
	return a>b;
}
int main() {
	 int n,maxn=0,minn=0;
	 cin>>n;
	 for(int i=0;i<n;i++)
	 cin>>a[i];
	 for(int i=0;i<n;i++)
	 cin>>b[i];
	 sort(a,a+n);	//从小到大排列
	 sort(b,b+n);
	 for(int i=0;i<n;i++) {
	 	maxn+=a[i]*b[i];  //就是最大的*最大的,第二大的*第二大的......
	}
	sort(b,b+n,cmp);
	for(int i=0;i<n;i++)
	minn+=a[i]*b[i]; 	//a的最小*b的最大,a的第二小*b的第二大
	 cout<<maxn<<" "<<minn;
}

方法二(这样写更巧妙):
#include<bits/stdc++.h>
using namespace std;
int a[1005],b[1005];
int n;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    sort(a+1,a+n+1);//从小到大排序
    for(int i=1;i<=n;i++)
    {
        cin>>b[i];
    }
    sort(b+1,b+n+1);
    long long num1=0,num2=0;
    for(int i=1;i<=n;i++)
    {
        num1+=a[i]*b[i];//最大乘最大,最小乘最小 最大值
        num2+=a[i]*b[n-i+1];//最大乘最小 最小值
    }
    printf("%lld %lld",num1,num2);
 
}
  • 11A.约数个数

p^q表示p的q次方,正整数M可以分解为M=(p1^a1)(p2^a2)(p3^a3)……(pn^an)的形式,其中p1,p2……pn为质数(大于1并且只能被1和自身整除的数叫做质数)。a1,a2……an为整数。例如18=(2^1)(3^2),45=(3^2)(5^1)。

给出n和一个质数g,以及正整数M分解后的形式,求M的所有约数中,有多少能被g整除。
第一反应是不是求出M然后找因数?那你就上当了,M可能很大很大的呢U•ェ•*U,这个题要注意pi是质数,并且g也是质数,所以如果,pi中没有g的话,M一定不会被g整除了,当pi里有g的时候就要看有多少个了。

upload successful

upload successful

tips:
m=(p1)^(x1)(p2)^(x2)(p3)^(x3)……
其中p1,p2,p3…是质数(素数),x1,x2,x3…是它们的指数
则m的约数的个数是(x1+1)
(x2+1)(x3+1)……
例如24=(2^3) (3^1)
所以其约数的个数为(3+1)
(1+1)=8个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[100],b[100];
int main()
{
    cin>>n>>m;
    int flag=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        if(a[i]==m) //如果存在ai==m
        {
            flag=i; //标记一下是第几个数
        }
    }
    for(int i=1;i<=n;i++)
    {
        cin>>b[i]; //bi是幂数
    }
    long long num=b[flag]; //g的幂数
    for(int i=1;i<=n;i++)
    {
        if(i!=flag)
            num+=num*b[i]; //上图推导出来的个数
    }
    if(!flag) //不存在直接为0
    {
        cout<<"0"<<endl;
    }
    else
        cout<<num<<endl;
}
  • 12 题目描述
      小明最近对折纸很感兴趣,他想知道一张正方形的纸在多次折叠以后沿纸的中线用剪刀将其剪开能得到多少张纸?
    输入
    第一行一个整数t,表示一共有t组数据(1 <= t <= 100)
    每组输入数据包括三行
    第一行为一个整数n,表示有n次操作(1 <= n <= 10^5)
      第二行为n个大写字母(四种情况L,R,T,B L表示从左向右折 R表示从右向左折 T表示从上向下折 B表示从下向上折)
      第三行为两个字母(四种情况 LR,RL,TB,BT LR表示从左向右剪 RL表示从右向左剪 TB表示从上往下剪 BT表示从下往上剪)
    输出
    输出一个整数表示能得到的纸的数目
    答案可能过大 需要对1000000007 (1e9+7)取模
    样例输入
    2

2
BB
LR

1
R
LR

样例输出
5
2
提示
所有的“对折”与“剪”的操作均沿中线进行

拿张纸模拟折叠找出来的规律,其实多模拟几次就会发现,左右方向剪只对上下方向叠有贡献,上下方向剪只对左右方向叠有贡献,所有就可以对应一下怎样剪的,然后只算另一个方向叠所形成的数量,然后也是多模拟几次会发现数量是2^k+1,k是折叠数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include<bits/stdc++.h>
using namespace std;
const long long Mod=1000000007;
char zhe[100005];
string jian;
int t,n;
int LR,TB;
int main()
{
    scanf("%d",&t);
    while(t--)
    {
       scanf("%d",&n);
       LR=0;
       TB=0;
       for(int i=0;i<n;i++)
       {
            cin>>zhe[i];
            if(zhe[i]=='R'||zhe[i]=='L')
            {
                LR++;//左右方向折叠次数
            }
            else
            {
                TB++;//上下方向折叠次数
            }
        }
        cin>>jian;
        long long num=1;
        if(jian=="LR"||jian=="RL")//左右方向剪
        {
            for(int i=1;i<=TB;i++)
            {
                num=num*2%Mod;
            }
            num+=1;
            cout<<num<<endl;
        }
        else //上下方向剪
        {
            for(int i=1;i<=LR;i++)
            {
                num=num*2%Mod;
            }
            num+=1;
            cout<<num<<endl;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
二分来做(https://www.cnblogs.com/violet-acmer/p/10020199.html):
步骤:
  (1):特判圆周长sum[ n ]是否整除3,如果不整除,直接输出"No"。
  (2):如果sum[ n ]整除3,遍历一遍数组,判断是否含有三点a,b,c,使得ab,bc,ca间的距离等于sum[ n ]/3,如果有,输出"Yes",否则输出"No"。
  
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=1e6+10;

int n;
int a[maxn];
int sum[maxn];

bool isSat(int p1,int p2){//判断p1,p2点是否在范围内
    return p1 <= sum[n] && p2 <= sum[n];
}
bool Check(int p1)//二分查找
{
    int l=0,r=n+1;
    while(r-l > 1)
    {
        int mid=l+((r-l)>>1);
        if(sum[mid] == p1)
            return true;
        if(sum[mid] < p1)
            l=mid;
        else
            r=mid;
    }
    return false;
}
char *Solve()
{
    if(sum[n]%3 != 0)//特判
        return "No";
    int d=sum[n]/3;
    for(int i=1;i <= n;++i)//遍历所有点,判断是否含有满足条件的三个点
    {
        int p1=sum[i]+d,p2=sum[i]+2*d;
        if(isSat(p1,p2) && Check(p1) && Check(p2))//二分查找点p2,p2是否存在
            return "Yes";//如果存在,返回"Yes"
    }
    return "No";
}
int main()
{
    scanf("%d",&n);
    sum[0]=0;
    for(int i=1;i <= n;++i)
        scanf("%d",a+i),sum[i]=sum[i-1]+a[i];//前缀和

    printf("%s\n",Solve());
}
  • 13L.寄蒜几盒

现在有一个圆圈,圆圈上有若干个点,请判断能否在若干个点中选择三个点两两相连组成一个等边三角形?
这若干个点在圆圈上按顺时针顺序分布。
如果可以的话输出”Yes”(不含引号)
不可以的话输出”No”(不含引号)

输入

第一行一个整数n,表示圆圈上有n个点
第二行n个整数,分别表示第1个点与第2个点之间圆弧的长度、第2个点与第3个点之间圆弧的长度······第n个点与第1个点之间圆弧的长度
3 <= n <= 10^6
1 <= x_i <= 1000 ( 1 <= i <= n)

我和继朋小朋友有两种不同解法,一个模拟查找+优化,一个利用二分查找,等会找他写一下二分的题解

方法一:弦长相等的话,那么对应的弧也相等,所以周长一定是3的倍数。因为给的是与前面一个点的距离,所以我们可以前缀和求周长,要想构成等边三角形那么三个点之间两两相距d=周长/3,怎么求两个不同点之间的距离呢?别忘了 给出的是前一个点与后一个点之间相隔的距离,那么,就可以利用区间和求两点之间的距离。优化一利用1/3周长和2/3周长做判断点,判断是否能够继续找,优化二 如果两个点相隔1/3周长,但找不到第三个点,这时候这两个点是不可能组成等边三角形了,所以有的话可以记录一下,然后跳过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include<bits/stdc++.h>
using namespace std;
int n;
int d[1000005];
bool vis[100005];
int main()
{
    cin>>n;
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        cin>>d[i];
        sum+=d[i];
    }
    if(sum%3)
    {
        printf("No\n");
        return 0;
    }
    else
    {
        int flag1=0,flag2=0,flag3=0;
        int s;
        for(int i=1;i<=n;i++)
        {
            if(vis[i])
            {
                continue;
            }
 
            s=0;
            flag2=0;//第一个距离d的点 
            flag3=0;//第二个
            for(int j=i;j<=n;j++)
            {
 
                s += d[j];  //区间和 求长度
                if(s==sum/3)//第一个点找到
                {
                    flag2=j;
                    vis[j]=1;
                }
                if(s>sum/3&&(!flag2))//弧长>1/3没找到第一个点
                {
                    break;
                }
                if(s==sum/3*2&&flag2)//第二个点找到
                {
                    flag3=1;
                    printf("Yes\n");
                    return 0;
                }
                if(s>sum/3*2&&(!flag3))//弧长>2/3没找到第二个点
                {
                    break;
                }
            }
        }
        printf("No\n");
    }
}
  • 14 一道c语言书上的题目
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
结构体中存入书的名字和价格,然后在下面求出最大的价格和最小的价格的书名
#include<iostream>
using namespace std;
struct book
{
	char n[10];
	int p;
}b[10];

int main()
{    int s,i;
	scanf("%d",&s);
	getchar();
	int max,min;
	for(i=0;i<s;i++)
	{
		scanf("programming is %s%d",b[i].n,&b[i].p);	
		getchar();//每次输完不处理那个回车的话,就会执行scanf来读取回车,这样就不符合逻辑了 
		//cin>>b[i].n>>b[i].p; //但是cin是不用向上面那样考虑吞掉回车的 
		if(i==0){
			min=i;
			max=i;
		} 
		if(b[max].p<b[i].p)
		max=i;
		if(b[min].p>b[i].p)
		min=i;
	}
	printf("%s%d",b[max].n,b[max].p);//最大值的数据
	printf("%s%d",b[min].n,b[min].p);//最小值的数据 
	return 0;
}
  • 15 提交时常见的错误
    如果出现编译错误(Compile Error),是不会执行的。每个题目都有一个标准的时间和内存限制,例如时间1000ms,内存65536K,程序在执行的时候会实时检查其花费时间和使用内存信息,如果出现超时和超内存将会分别返回Time Limit Exceeded和Memory Limit Exceeded错误信息,如果程序执行时出现错误,比如非法指针,数组越界等,将会返回Runtime Error信息。如果你的程序没有出现上面的信息,说明程序顺利执行结束了。接下来,就是对你的程序的输出也就是运行结果进行检查,如果你的执行结果和我们的标准答案完全一样,则返回Accepted,也就说明你这个题目做对了。如果除去空格,换行,tab外完全相同,则说明你的代码格式错误,将返回Presentation Error(比如多输出了什么空格啥的),如果你输出的内容有一部分和标准答案完全一样,但是还输出了一些其他内容,则说明你多输出了,这时候将返回Output Limit Exceeded错误信息,出现其他情况,就说明你的输出结果和标准答案不一样,就是Wrong Answer了。

总结一下错误的出现顺序:

Compile Error -> Memory Limit Exceeded = Time Limit Exceeded = Runtime Error -> Wrong Answer -> Output Limit Exceeded ->Presentation Error -> Accepted

其中:Runtime Error
(ACCESS_VIOLATION) runtime error (运行时错误)就是程序运行到一半,程序就崩溃了。
当出现这种错误时,先看看定义的范围是不是与题目不符,比如题目要求m<1000,定义数组时只定义为a[100],这种错误多次出现。一定要注意题目中数据的范围!
如果不是这种错误,还有可能是程序太麻烦,太复杂

比如说:
①除以零
②数组越界:int a[3]; a[10000000]=10;
③指针越界:int p; p=(int )malloc(5 sizeof(int)); (p+1000000)=10;
④使用已经释放的空间:int p; p=(int )malloc(5 sizeof(int));free(p); p=10;
⑤数组开得太大,超出了栈的范围,造成栈溢出:int a[100000000];

  • 16
  • 17
  • 18
  • 19
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值