简单STL(顺序不按正常顺序或者只抽几个的就别用这个了)
经过学习stl发现有一些共同之处,也有一些不同之处以下为总结:
总规律:string全用下标;vector,map取元素用下标,函数用迭代器;其他的全用迭代器;结尾基本是最后的后一位
1.基本操作一般有:初始化,输入,输出(访问),插入,替换,查找,删除,开始结束
1初始化:vector用(数量 ,值 )初始化,set貌似没有能直接赋值的,string直接”=“赋值,map用‘=’赋值,或者用fill
2输入:vector push_back() 从0开始,set用insert()从0开始,string输入函数,map同上
3输出:vector 可以用下标可以用迭代器,set可以用迭代器,string可以用下标可以用迭代器也可以用substr(pos,len)的返回值,map可以用下标可以用迭代器(it->first,it->second)(迭代器注意1以!=end()为循环结尾,2用指针输出)
4插入:vector insert(迭代器,元素),set同上,string insert(pos, string)
## 6查找:vector无,set ,string,map find()返回迭代器(string find(str2,pos))
## 7删除:set删除单个元素为名字,其他填迭代器,删除整段是一样的
## 8开始结束:vector set map用begin()end()queue是front() back()
1vector
1089 狼人杀-简单版 (20分)
以下文字摘自《灵机一动·好玩的数学》:“狼人杀”游戏分为狼人、好人两大阵营。在一局“狼人杀”游戏中,1 号玩家说:“2 号是狼人”,2 号玩家说:“3 号是好人”,3 号玩家说:“4 号是狼人”,4 号玩家说:“5 号是好人”,5 号玩家说:“4 号是好人”。已知这 5 名玩家中有 2 人扮演狼人角色,有 2 人说的不是实话,有狼人撒谎但并不是所有狼人都在撒谎。扮演狼人角色的是哪两号玩家?
本题是这个问题的升级版:已知 N 名玩家中有 2 人扮演狼人角色,有 2 人说的不是实话,有狼人撒谎但并不是所有狼人都在撒谎。要求你找出扮演狼人角色的是哪几号玩家?
输入格式:
输入在第一行中给出一个正整数 N(5≤N≤100)。随后 N 行,第 i 行给出第 i 号玩家说的话(1≤i≤N),即一个玩家编号,用正号表示好人,负号表示狼人。
输出格式:
如果有解,在一行中按递增顺序输出 2 个狼人的编号,其间以空格分隔,行首尾不得有多余空格。如果解不唯一,则输出最小序列解 —— 即对于两个序列 A=a[1],...,a[M] 和 B=b[1],...,b[M],若存在 0≤k<M 使得 a[i]=b[i] (i≤k),且 a[k+1]<b[k+1],则称序列 A 小于序列 B。若无解则输出 No Solution。
输入样例 1:
5
-2
+3
-4
+5
+4
输出样例 1:
1 4
输入样例 2:
6
+6
+3
+1
-5
-2
+4
输出样例 2(解不唯一):
1 5
输入样例 3:
5
-2
-3
-4
-5
-1
//一道有意思的数学转换题正负号判断真是没想到,参考柳神代码
//此题先判断是好是狼再判断说谎的人好做
//用vector做是因为初始化的方便从而配凑正负号
输出样例 3:
No Solution
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<vector>
#include<math.h>
using namespace std;
int main()
{
int n;
scanf("%d", &n);
vector <int> v(n + 1);//用小括号而不是中括号
for (int i = 1; i <= n; i++)
{
cin >> v[i];
}
for (int i = 1; i <= n; i++)
{
for (int j = i + 1; j <= n; j++)
{
vector <int> a(n + 1, 1), lie;
a[i] = -1;
a[j] = -1;
for (int w = 1; w <= n; w++)
{
if (v[w] * a[abs(v[w])] < 0)
{
lie.push_back(w);
}
}
if (lie.size() == 2 && a[lie[0]] + a[lie[1]] == 0)
{
printf("%d %d", i, j);
return 0;
}
}
}
printf("No Solution");
return 0;
}
1.2vector两种用法
1.数组法(完全当数组用直接用下标赋值)(insert()是个好用的函数)不用写循环了【手动狗头】
2.不定长数组只能用push——back()
两者不要混着用容易找不着空间大小真正是什么
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
vector<int> v(n);
for(int i=0;i<=n-1;i++) scanf("%d",&v[i]);
int a;
scanf("%d",&a);
vector<int>::iterator it;
it=lower_bound(v.begin(),v.end(),a);
v.insert(it,a);
for(int i=0;i<=n;i++) printf("%d ",v[i]);
}
2string
2.1也不是所有字符串用string都方便,如果有字符串转化为数字,或数字转化为字符串的题还是用字符数组中的sscanf和sprintf函数比较好
/*1054 求平均值 (20分)
本题的基本要求非常简单:给定 N 个实数,计算它们的平均值。但复杂的是有些输入数据可能是非法的。一个“合法”的输入是 [−1000,1000] 区间内的实数,并且最多精确到小数点后 2 位。当你计算平均值的时候,不能把那些非法的数据算在内。
输入格式:
输入第一行给出正整数 N(≤100)。随后一行给出 N 个实数,数字间以一个空格分隔。
输出格式:
对每个非法输入,在一行中输出 ERROR: X is not a legal number,其中 X 是输入。最后在一行中输出结果:The average of K numbers is Y,其中 K 是合法输入的个数,Y 是它们的平均值,精确到小数点后 2 位。如果平均值无法计算,则用 Undefined 替换 Y。如果 K 为 1,则输出 The average of 1 number is Y。
输入样例 1:
7
5 -3.2 aaa 9999 2.3.4 7.123 2.35
输出样例 1:
ERROR: aaa is not a legal number
ERROR: 9999 is not a legal number
ERROR: 2.3.4 is not a legal number
ERROR: 7.123 is not a legal number
The average of 3 numbers is 1.38
输入样例 2:
2
aaa -9999
输出样例 2:
ERROR: aaa is not a legal number
ERROR: -9999 is not a legal number
The average of 0 numbers is Undefined
作者: CHEN, Yue
单位: 浙江大学
时间限制: 400 ms
内存限制: 64 MB
*/
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
int main()
{
char a[1000], b[1000];
int n;
scanf("%d", &n);
double sum = 0.0;
int cnt = 0;
for (int i = 1; i <= n; i++)
{
double temp;
scanf("%s", a);
sscanf(a, "%lf", &temp);//检验浮点数是否正确强大的办法,此时不要用string~\(≧▽≦)/~啦啦啦
sprintf(b, "%.2f", temp);//注意这两个函数一边必为字符数组,而且方向相反,所以需要两个函数
int flag = 0;
for (int j = 0; j <= strlen(a) - 1; j++)//这里检验
{
if (a[j] != b[j])
{
flag = 1;
break;
}
}
if (flag || temp>1000 || temp<-1000)
{
printf("ERROR: %s is not a legal number\n", a);
}
else
{
sum += temp;
cnt++;
}
}
if (cnt == 1)
printf("The average of 1 number is %.2f\n", sum);
else if (cnt > 1)
printf("The average of %d numbers is %.2f\n", cnt, sum / cnt);
else
printf("The average of 0 numbers is Undefined\n");
return 0;
}
2.2转义字符的特殊输出注意一下,还有可以用vector来实现多维字符数组,vector没办法只能从0开始
/*1052 卖个萌 (20分)
萌萌哒表情符号通常由“手”、“眼”、“口”三个主要部分组成。简单起见,我们假设一个表情符号是按下列格式输出的:
[左手]([左眼][口][右眼])[右手]
现给出可选用的符号集合,请你按用户的要求输出表情。
输入格式:
输入首先在前三行顺序对应给出手、眼、口的可选符号集。每个符号括在一对方括号 []内。题目保证每个集合都至少有一个符号,并不超过 10 个符号;每个符号包含 1 到 4 个非空字符。
之后一行给出一个正整数 K,为用户请求的个数。随后 K 行,每行给出一个用户的符号选择,顺序为左手、左眼、口、右眼、右手——这里只给出符号在相应集合中的序号(从 1 开始),数字间以空格分隔。
输出格式:
对每个用户请求,在一行中输出生成的表情。若用户选择的序号不存在,则输出 Are you kidding me? @\/@。
输入样例:
[╮][╭][o][~\][/~] [<][>]
[╯][╰][^][-][=][>][<][@][⊙]
[Д][▽][_][ε][^] ...
4
1 1 2 2 2
6 8 1 5 5
3 3 4 3 3
2 10 3 9 3
输出样例:
╮(╯▽╰)╭
<(@Д=)/~
o(^ε^)o
Are you kidding me? @\/@
*///数组,啥的从0开始用,因为stl里vector从0开始用以后养成习惯。
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<vector<string> > v;
for (int i = 0; i < 3; i++) {
string s;
getline(cin, s);
vector<string> row;
int j = 0, k = 0;
while (j < s.length()) {
if (s[j] == '[') {
while (k++ < s.length()) {
if (s[k] == ']') {
row.push_back(s.substr(j + 1, k - j - 1));
break;
}
}
}
j++;
}
v.push_back(row);
}
int n;
cin >> n;
for (int i = 0; i < n; i++) {
int a, b, c, d, e;
cin >> a >> b >> c >> d >> e;
if (a > v[0].size() || b > v[1].size() || c > v[2].size() || d > v[1].size() || e > v[0].size() || a < 1 || b < 1 || c < 1 || d < 1 || e < 1) {
cout << "Are you kidding me? @\\/@" << endl;//此处转义字符输出规则&//n等输出这种字符时应注意
continue;
}
cout << v[0][a - 1] << "(" << v[1][b - 1] << v[2][c - 1] << v[1][d - 1] << ")" << v[0][e - 1] << endl;
}
return 0;
}
2.3判断字母与数字的
/*1081 检查密码 (15分)
本题要求你帮助某网站的用户注册模块写一个密码合法性检查的小功能。该网站要求用户设置的密码必须由不少于6个字符组成,并且只能有英文字母、数字和小数点 .,还必须既有字母也有数字。
输入格式:
输入第一行给出一个正整数 N(≤ 100),随后 N 行,每行给出一个用户设置的密码,为不超过 80 个字符的非空字符串,以回车结束。
输出格式:
对每个用户的密码,在一行中输出系统反馈信息,分以下5种:
如果密码合法,输出Your password is wan mei.;
如果密码太短,不论合法与否,都输出Your password is tai duan le.;
如果密码长度合法,但存在不合法字符,则输出Your password is tai luan le.;
如果密码长度合法,但只有字母没有数字,则输出Your password needs shu zi.;
如果密码长度合法,但只有数字没有字母,则输出Your password needs zi mu.。
输入样例:
5
123s
zheshi.wodepw
1234.5678
WanMei23333
pass*word.6
输出样例:
Your password is tai duan le.
Your password needs shu zi.
Your password needs zi mu.
Your password is wan mei.
Your password is tai luan le.
作者: CHEN, Yue
单位: 浙江大学
时间限制: 400 ms
内存限制: 64 MB
代码长度限制: 16 KB
*/
#include <iostream>
#include <cctype>//使用函数的必要
using namespace std;
int main() {
int n;
cin >> n; getchar();
for (int i = 0; i < n; i++) {
string s;
getline(cin, s);
if (s.length() >= 6) {
int invalid = 0, hasAlpha = 0, hasNum = 0;
for (int j = 0; j < s.length(); j++) {
if (s[j] != '.' && !isalnum(s[j])) invalid = 1;
else if (isalpha(s[j])) hasAlpha = 1;//是否为英文字母不是则返回0 还有isupper(大写字母)和islower(小写字母)
else if (isdigit(s[j])) hasNum = 1;//是否为数字不是则返回0
}
if (invalid == 1) cout << "Your password is tai luan le.\n";
else if (hasNum == 0) cout << "Your password needs shu zi.\n";
else if (hasAlpha == 0) cout << "Your password needs zi mu.\n";
else cout << "Your password is wan mei.\n";
}
else
cout << "Your password is tai duan le.\n";
}
return 0;
}
2.4补0加进制转换
/*1074 宇宙无敌加法器 (20分)
地球人习惯使用十进制数,并且默认一个数字的每一位都是十进制的。而在 PAT 星人开挂的世界里,每个数字的每一位都是不同进制的,这种神奇的数字称为“PAT数”。每个 PAT 星人都必须熟记各位数字的进制表,例如“……0527”就表示最低位是 7 进制数、第 2 位是 2 进制数、第 3 位是 5 进制数、第 4 位是 10 进制数,等等。每一位的进制 d 或者是 0(表示十进制)、或者是 [2,9] 区间内的整数。理论上这个进制表应该包含无穷多位数字,但从实际应用出发,PAT 星人通常只需要记住前 20 位就够用了,以后各位默认为 10 进制。
在这样的数字系统中,即使是简单的加法运算也变得不简单。例如对应进制表“0527”,该如何计算“6203 + 415”呢?我们得首先计算最低位:3 + 5 = 8;因为最低位是 7 进制的,所以我们得到 1 和 1 个进位。第 2 位是:0 + 1 + 1(进位)= 2;因为此位是 2 进制的,所以我们得到 0 和 1 个进位。第 3 位是:2 + 4 + 1(进位)= 7;因为此位是 5 进制的,所以我们得到 2 和 1 个进位。第 4 位是:6 + 1(进位)= 7;因为此位是 10 进制的,所以我们就得到 7。最后我们得到:6203 + 415 = 7201。
输入格式:
输入首先在第一行给出一个 N 位的进制表(0 < N ≤ 20),以回车结束。 随后两行,每行给出一个不超过 N 位的非负的 PAT 数。
输出格式:
在一行中输出两个 PAT 数之和。
输入样例:
30527
06203
415
输出样例:
7201
*/
#include<iostream>
#include<string>
using namespace std;
int main()
{
string a, b, c;
cin >> a;
cin >> b;
cin >> c;
string temp1(a.length() - b.length(), '0');//补0操作
string temp2(a.length() - c.length(), '0');
b = temp1 + b;
c = temp2 + c;
string ans;//初始化很重要
ans = a;
int jinwei = 0;
for (int i = a.length() - 1; i >= 0; i--)
{
if (a[i] == '0')
{
a[i] = 10 + '0';
}
ans[i] = (b[i] - '0' + c[i] - '0' + jinwei) % (a[i] - '0') + '0';
jinwei = (b[i] - '0' + c[i] - '0' + jinwei) / (a[i] - '0');
}
if (jinwei != 0)
{
ans = '1'+ ans;
}
int flag = 0;
for (int i = 0; i <= ans.length() - 1; i++)//此次从前往后处理
{
if (ans[i] != '0'|| flag == 1)//巧妙的只过一次
{
flag = 1;
cout << ans[i];
}
}
if (flag == 0)//只有一个0的特判
{
cout << 0;
}
return 0;
}
2.5压缩与解压缩字符与数字的转换
/*1084 外观数列 (20分)
外观数列是指具有以下特点的整数序列:
d, d1, d111, d113, d11231, d112213111, ...
它从不等于 1 的数字 d 开始,序列的第 n+1 项是对第 n 项的描述。比如第 2 项表示第 1 项有 1 个 d,所以就是 d1;第 2 项是 1 个 d(对应 d1)和 1 个 1(对应 11),所以第 3 项就是 d111。又比如第 4 项是 d113,其描述就是 1 个 d,2 个 1,1 个 3,所以下一项就是 d11231。当然这个定义对 d = 1 也成立。本题要求你推算任意给定数字 d 的外观数列的第 N 项。
输入格式:
输入第一行给出 [0,9] 范围内的一个整数 d、以及一个正整数 N(≤ 40),用空格分隔。
输出格式:
在一行中给出数字 d 的外观数列的第 N 项。
输入样例:
1 8
输出样例:
1123123111
#include<stdio.h>
#include<string.h>
int main()
{
int n;
char s[100000];
scanf("%s %d", s, &n);
for (int i = 2; i <= n; i++)
{
int geshu = 1;
int c = -2;
char temp[100000];
int len = strlen(s) - 1;//能放少循环就放少循环不然超时
for (int j = 0; j <= len; j++)//最主要的步骤一个个统计字符个数及字符
{
if (s[j] == s[j + 1])
{
geshu++;
}
else
{
c = c + 2;
temp[c] = s[j];
temp[c + 1] = geshu + '0';
geshu = 1;//个数归1
}
}
strcpy(s, temp);
}
puts(s);
return 0;
}
*/
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
int n, j;
cin >> s >> n;
for (int cnt = 1; cnt < n; cnt++)
{
string t;
for (int i = 0; i <= s.length() - 1; i = j)//一段一段的巧妙处理
{
for (j = i; j <= s.length() - 1 && s[j] == s[i]; j++);//注意此处的分号
{
t += s[i] + to_string(j - i);数字变字符串
}
}
s = t;
}
cout << s;
return 0;
}
2.6string也有数组,<<前后尽量有空格,就算是string输入有数字变为字符串时也要加getchar()
/*1044 火星数字 (20分)
火星人是以 13 进制计数的:
地球人的 0 被火星人称为 tret。
地球人数字 1 到 12 的火星文分别为:jan, feb, mar, apr, may, jun, jly, aug, sep, oct, nov, dec。
火星人将进位以后的 12 个高位数字分别称为:tam, hel, maa, huh, tou, kes, hei, elo, syy, lok, mer, jou。
例如地球人的数字 29 翻译成火星文就是 hel mar;而火星文 elo nov 对应地球数字 115。为了方便交流,请你编写程序实现地球和火星数字之间的互译。
输入格式:
输入第一行给出一个正整数 N(<100),随后 N 行,每行给出一个 [0, 169) 区间内的数字 —— 或者是地球文,或者是火星文。
输出格式:
对应输入的每一行,在一行中输出翻译后的另一种语言的数字。
输入样例:
4
29
5
elo nov
tam
输出样例:
hel mar
may
115
13
*/
#include <iostream>
#include <string>
using namespace std;
string a[13] = { "tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec" };//string也可以用数组
string b[13] = { "####", "tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou" };
string s;
int len;
int main()
{
int n;
scanf("%d", &n);
getchar();//不论用什么输入函数都要注意是都用这个
for (int i = 1; i <= n; i++)
{
getline(cin, s);
len = s.length();
if (s[0] >= '0'&&s[0] <= '9')
{
int shu;
shu = stoi(s);
if (shu / 13 == 0)
{
cout<< a[shu % 13] << endl;//<<前后尽量有空格
}
else
{
if (shu % 13 == 0)//同样是思维难题对于13的倍数有特判,一个东西读错了要联想其他的有没有理解错误
{
cout << b[shu / 13] << endl;
}
else
{
cout << b[shu / 13] << " " << a[shu % 13] << endl;
}
}
}
else
{
if (len == 3)
{
string s1;
s1 = s.substr(0, 3);
for (int i = 0; i <= 12; i++)
{
if (a[i] == s1)
{
cout << i << endl;
break;
}
if (b[i] == s1)
{
cout << i * 13 << endl;//题目中思维难题,(第二遍读应当多想其他的情况)
break;
}
}
}
else
{
string s1, s2;
s1 = s.substr(0, 3);
s2 = s.substr(4, 3);
int sum = 0;
for (int i = 1; i <= 12; i++)
{
if (b[i] == s1)
{
sum += 13*i;
break;
}
}
for (int i = 0; i <= 12; i++)
{
if (a[i] == s2)
{
sum += i;
break;
}
}
cout << sum << endl;
}
}
}
return 0;
}
2.7to_string()int转成string,还有就是看题看傻了而且reverse(容器的话是用迭代器的)
/*
1001 A+B Format (20分)
Calculate a+b and output the sum in standard format -- that is, the digits must be separated into groups of three by commas (unless there are less than four digits).
Input Specification:
Each input file contains one test case. Each case contains a pair of integers a and b where −10
6
≤a,b≤10
6
. The numbers are separated by a space.
Output Specification:
For each test case, you should output the sum of a and b in one line. The sum must be written in the standard format.
Sample Input:
-1000000 9
Sample Output:
-999,991
看题看傻了而且reverse(容器的话是用迭代器的)
*/
#include<iostream>
#include<string>
#include<algorithm>
#include<stdio.h>
using namespace std;
int main()
{
int a, b;
cin >> a >> b;
string ans = to_string(a + b);
int shu = ans.size() - 1;
string answer;
if (ans[0] == '-')
{
for (int i = shu; i >= 1; i--)
{
answer += ans[i];
if ((shu - i + 1) % 3 == 0 && i != 1) answer += ",";
}
answer += "-";
}
else
{
for (int i = shu; i >= 0; i--)
{
answer += ans[i];
if ((shu - i + 1) % 3 == 0 && i != 0) answer += ",";
}
}
int ansshu = answer.size();
reverse(answer.begin(),answer.begin()+ansshu);
cout << answer;
return 0;
}
3map(锤子呀,这些奇技淫巧都用不到~~~~)
3.1一对一普通map够用,一对多(开vector)则,散列与map结合,适当的逆向思考
/*1090 危险品装箱 (25分)
集装箱运输货物时,我们必须特别小心,不能把不相容的货物装在一只箱子里。比如氧化剂绝对不能跟易燃液体同箱,否则很容易造成爆炸。
本题给定一张不相容物品的清单,需要你检查每一张集装箱货品清单,判断它们是否能装在同一只箱子里。
输入格式:
输入第一行给出两个正整数:N (≤10
4
) 是成对的不相容物品的对数;M (≤100) 是集装箱货品清单的单数。
随后数据分两大块给出。第一块有 N 行,每行给出一对不相容的物品。第二块有 M 行,每行给出一箱货物的清单,格式如下:
K G[1] G[2] ... G[K]
其中 K (≤1000) 是物品件数,G[i] 是物品的编号。简单起见,每件物品用一个 5 位数的编号代表。两个数字之间用空格分隔。
输出格式:
对每箱货物清单,判断是否可以安全运输。如果没有不相容物品,则在一行中输出 Yes,否则输出 No。
输入样例:
6 3
20001 20002
20003 20004
20005 20006
20003 20001
20005 20004
20004 20006
4 00001 20004 00002 20003
5 98823 20002 20003 20006 10010
3 12345 67890 23333
输出样例:
No
Yes
Yes
#include<map>//超时强行暴力做法第三个测试点超时,还有一种使用map散列结合(其中map只是个函数的作用)
#include<stdio.h>
#include<vector>
using namespace std;
int main()
{
int n, m;
scanf("%d %d", &n, &m);
map<int,vector <int>> ma;//想要
for (int i = 1; i <= n; i++)
{
int temp1, temp2;
scanf("%d %d", &temp1, &temp2);
ma[temp1].push_back(temp2) ;
ma[temp2].push_back(temp1);
}
for (int i = 1; i <= m; i++)
{
int k;
scanf("%d", &k);
int a[1010] = {0};
for (int j = 1; j <= k; j++)
{
scanf("%d", &a[j]);
}
int flag = 0;
for (int x = 1; x <= k; x++)
{
for (int j = x + 1; j <= k; j++)
{
for (int w = 0; w < ma[a[x]].size(); w++)
{
if (ma[a[x]][w]==a[j])
{
flag = 1;
break;
}
}
if (flag == 1)
{
break;
}
}
if (flag == 1)
{
break;
}
}
if (flag == 1)
{
printf("No\n");
}
else
{
printf("Yes\n");
}
}
return 0;
}*/
#include<map>//超时强行暴力做法第三个测试点超时,还有一种使用map散列结合(其中map只是个函数的作用)
#include<stdio.h>
#include<vector>
using namespace std;
int main()
{
int n, m;
scanf("%d %d", &n, &m);
map<int, vector <int>> ma;//想要
for (int i = 1; i <= n; i++)
{
int temp1, temp2;
scanf("%d %d", &temp1, &temp2);
ma[temp1].push_back(temp2);
ma[temp2].push_back(temp1);
}
for (int i = 1; i <= m; i++)
{
int k;
scanf("%d", &k);
int v[1010] = { 0 };
int mp[100000] = { 0 };
for (int j = 1; j <= k; j++)
{
scanf("%d", &v[j]);
mp[v[j]]++;
}
int flag = 0;
for (int j = 1; j <= k; j++)
{
for (int w = 0; w < ma[v[j]].size(); w++)
{
if (mp[ma[v[j]][w]] == 1)
{
flag = 1;
break;
}
}
if (flag == 1)
{
break;
}
}
if (flag == 1)
{
printf("No\n");
}
else
{
printf("Yes\n");
}
}
return 0;
}
3.2 map的一对一应用
/*1065 单身狗 (25分)
“单身狗”是中文对于单身人士的一种爱称。本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱。
输入格式:
输入第一行给出一个正整数 N(≤ 50 000),是已知夫妻/伴侣的对数;随后 N 行,每行给出一对夫妻/伴侣——为方便起见,每人对应一个 ID 号,为 5 位数字(从 00000 到 99999),ID 间以空格分隔;之后给出一个正整数 M(≤ 10 000),为参加派对的总人数;随后一行给出这 M 位客人的 ID,以空格分隔。题目保证无人重婚或脚踩两条船。
输出格式:
首先第一行输出落单客人的总人数;随后第二行按 ID 递增顺序列出落单的客人。ID 间用 1 个空格分隔,行的首尾不得有多余空格。
输入样例:
3
11111 22222
33333 44444
55555 66666
7
55555 44444 10000 88888 22222 11111 23333
输出样例:
5
10000 23333 44444 55555 88888
*/
#include<map>
#include<stdio.h>
#include<set>
using namespace std;
int main()
{
map<int, int> mp;
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
int temp1;
int temp2;
scanf("%d %d", &temp1, &temp2);
mp[temp1] = temp2;
mp[temp2] = temp1;
}
int m;
scanf("%d", &m);
set <int> daan;
int ma[100000] = { 0 };
int v[100000] = { 0 };
for (int i = 1; i <= m; i++)
{
int temp;
scanf("%d", &temp);
ma[temp] = 1;
v[i] = temp;
}
int w = 0;
for (int i = 1; i <= m; i++)
{
if (ma[mp[v[i]]] == 0)
{
w++;
daan.insert(v[i]);//暂时只有vector有push_back()等函数,set使用insert,map直接类似数组建立,string等号赋值
}
}
printf("%d\n", daan.size());
for (set<int>::iterator it = daan.begin(); it != daan.end(); it++)
{
if (it == daan.begin())
{
printf("%05d", *it);
}
else
{
printf(" %05d", *it);
}
}
return 0;
}
3.3map的真正好用的用法(散列)(查找不知道存不存在的元素就用find就行想减少时间复杂度使用(unordered_map))(摘自October的代码)
至此map完全可以替代数组映射了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
const int INF = 1e9 + 7;
int ans,num[1002];
map<int,int>mp;
int main()
{
int n;
scanf("%d",&n);
for(int i = 1;i <= n;i ++ )
{
scanf("%d",&num[i]);
mp[num[i]] ++ ;
if(mp[num[i]] > mp[ans]) ans = num[i];
}
printf("%d %d",ans,mp[ans]);
return 0;
}
4set
/*1064 朋友数 (20分)
如果两个整数各位数字的和是一样的,则被称为是“朋友数”,而那个公共的和就是它们的“朋友证号”。例如 123 和 51 就是朋友数,因为 1+2+3 = 5+1 = 6,而 6 就是它们的朋友证号。给定一些整数,要求你统计一下它们中有多少个不同的朋友证号。
输入格式:
输入第一行给出正整数 N。随后一行给出 N 个正整数,数字间以空格分隔。题目保证所有数字小于 10
4
。
输出格式:
首先第一行输出给定数字中不同的朋友证号的个数;随后一行按递增顺序输出这些朋友证号,数字间隔一个空格,且行末不得有多余空格。
输入样例:
8
123 899 51 998 27 33 36 12
输出样例:
4
3 6 9 26
作者: CHEN, Yue
单位: 浙江大学
时间限制: 400 ms
内存限制: 64 MB
代码长度限制: 16 KB
*/
#include<iostream>
#include<string>
#include<stdio.h>
#include<set>
using namespace std;
int main()
{
int n;
scanf("%d", &n);
getchar();
set<int> jihe;
string l;
for (int i = 1; i <= n; i++)
{
cin >> l;
int temp = 0;
for (int j = 0; j<l.size(); j++)
{
temp += l[j] - '0';
}
jihe.insert(temp);
}
printf("%d\n", jihe.size());
for (set<int> ::iterator it = jihe.begin(); it != jihe.end(); it++)
{
if (it == jihe.begin())
{
printf("%d", *it);
}
else
{
printf(" %d", *it);
}
}
return 0;
}