hash-map, printf-cout, string的printf输出
1047(时间限制, hash思想)
//map是通过键值排序的
//1.第一次用map, 时间超限两个
//2.第二次, 用hash, 输出string用cout, 时间超限一个
//3.第三次, 用hash,输出string用%s, str.c_str(), 通过
//4.逻辑不变, 小小的几个改动就能影响好多样例
//1.核心: 学会辨别使用STL, 然后又时间限制的题目
//2.想要用 printf()输出string, 用%s, str.c_str()
//3.set不比vector.sort省时间
//4.组织代码时尽量按最省的来
//5.能用数组hash, 就尽量不要用map
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
int n, k;
vector<vector<string> >results;
int main() {
scanf("%d %d", &n, &k);
results.resize(k + 1);
for (int i = 0; i < n; i++) {
string str;
int num, tmp;
cin >> str;
scanf("%d", &num);
for (int j = 0; j < num; j++) {
scanf("%d", &tmp);
results[tmp].push_back(str);
}
}
for (int i = 1; i < results.size(); i++) {
sort(results[i].begin(), results[i].end());
}
for (int i = 1; i < results.size(); i++) {
printf("%d %d\n", i, results[i].size());
//set<string>::iterator it;
for (int j=0; j<results[i].size(); j++) printf("%s\n", results[i][j].c_str());
}
return 0;
}
map-unordered_map(同上一题)+给string赋予唯一的id(即不用map)
1039(时间限制, hash思想)
//1.时间超限的一种表示方式是时间:--, 内存:0
//2.将map改为unordered_map, 最后一个样例通过
//3.!!!!同样一个代码, 四次提交, 两次过, 两次超时
//核心: 给任意字符串唯一的数字ID
// int get_id(string str){
// int id=0;
// for(int i=0;i<str.length();i++)
// id=id*进制+str[i]-'A';
// return id;
// }
//很简单的: 只不过在每次访问下标之前, 调用get_id函数
//第二次应证, 用set替代vector一点用都没有
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <set>
#include <algorithm>
using namespace std;
const int MAX = 26 * 26 * 26 * 10 + 10;
int n, k;
//unordered_map<string, vector<int> >inputs;
//unordered_map<string, set<int> >inputs;
vector<vector<int> >inputs(MAX);
int get_id(string str) {
int id = 0;
for (int i = 0; i < 3; i++) {
id = id * 26 + str[i] - 'A';
}
id = id * 10 + str[3] - '0';
return id;
}
int main() {
scanf("%d %d", &n, &k);
for (int i = 0; i < k; i++) {
int id, num;
string str;
scanf("%d %d", &id, &num);
for (int i = 0; i < num; i++) {
cin >> str;
//int MM = get_id(str);
//printf("MM: %d\n", MM);
inputs[get_id(str)].push_back(id);
}
}
排序
//unordered_map<string, vector<int> >::iterator it;
//for (it= inputs.begin(); it!=inputs.end(); it++) {
// sort(it->second.begin(), it->second.end());
//}
//
for (int i = 0; i < n; i++) {
string str;
cin >> str;
if (inputs[get_id(str)].size() == 0) {
printf("%s 0\n", str.c_str());
continue;
}
sort(inputs[get_id(str)].begin(), inputs[get_id(str)].end());
printf("%s %d", str.c_str(), inputs[get_id(str)].size());
for (int j = 0; j < inputs[get_id(str)].size(); j++) printf(" %d", inputs[get_id(str)][j]);
//set<int>::iterator it;
//for (it = inputs[str].begin(); it != inputs[str].end(); it++)printf(" %d", *it);
printf("\n");
}
return 0;
}
map的使用, string的处理(别人代码)(放到字母哈希里了)
1112
// 1.读懂题目设计好逻辑很重要
// 2.string如果想擦除某些字符的话, 其实也可以replace(起点,个数, "");
// 3.map可以直接erase擦除键, 而不是iterator
#include<iostream>
#include<string>
#include<algorithm>
#include<map>
using namespace std;
string s;
int k;
bool a[127] = { false };//ascii
map<char, int> ma;
int main()
{
cin >> k >> s;
for (int i = 0; i < s.size(); i++)
{
ma[s[i]]++;
}
map<char, int>::iterator it = ma.begin();
for (it; it != ma.end(); it++)
{
char c = it->first; int ccount = it->second;
if (ccount%k != 0) a[c] = true;//not stucked
else
{
int j = 0;
while (j < s.size())
{
int count = 0;
while(s[j] == c)
{
j++; count++;
}
if (count&&count%k != 0) { a[c] = true; break; }
else j++;
}
}
}
int i = 0;
bool print[128] = { false };
while(i<s.size())
{
if (a[s[i]] == false)//stucked
{
if (!print[s[i]])
{
cout << s[i];
print[s[i]] = true;
}
s.replace(i, k - 1, "");
}
i++;
}
cout << endl << s;
return 0;
}
map的使用
1054
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>
using namespace std;
map<string, int>mp;
string a;
string ans;
int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < n * m; ++i)
{
cin >> a;
mp[a]++;
if (mp[a] >= n * m / 2)
ans = a;
}
cout << ans << endl;
return 0;
}
set的使用,找相同不同思想很巧妙(柳神代码)
1063
//1.请注意最后一行, % 的输出
#include <cstdio>
#include <vector>
#include <set>
using namespace std;
int main() {
int n, m, k, temp, a, b;
scanf("%d", &n);
vector<set<int>> v(n);
for(int i = 0; i < n; i++) {
scanf("%d", &m);
set<int> s;
for(int j = 0; j < m; j++) {
scanf("%d", &temp);
s.insert(temp);
}
v[i] = s;
}
scanf("%d", &k);
for(int i = 0; i < k; i++) {
scanf("%d %d", &a, &b);
int nc = 0, nt = v[b-1].size(); //注意初值, 这里思想很巧妙
for(auto it = v[a-1].begin(); it != v[a-1].end(); it++) {
if(v[b-1].find(*it) == v[b-1].end())
nt++;
else
nc++;
}
double ans = (double)nc / nt * 100;
printf("%.1f%%\n", ans);
}
return 0;
}
——————————————————————————————
栈
——————————————————————————————
stack+判断是否正确pop队列
1051
// 1.核心: 寻找唯一能使成功的情况, 剩下的情况都为false
//2.stray 非ASCII字符
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
int main(){
int m,n,k;
cin>>m>>n>>k;
for(int i=0;i<k;i++){
bool flag=false;
stack<int> s;
vector<int> v(n);//0~size-1
for(int j=0;j<n;j++){
scanf("%d",&v[j]);
}
int index=0;
for(int j=1;j<=n;j++){
s.push(j);
if(s.size()>m) break;
while(!s.empty()&&s.top()==v[index]){
s.pop();
index++;
}
}
if(index==n) flag=true;
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}
————————————————————————————————
map,set的使用
1054
1039
1047
1063
1022