HDU3627 Giant For
代码也是看了别人的才做出来,在此自我反省
(本题要求找出minnium(>row,>col)点,且是先找minnium(>row)再找minnium(>col))
本次涉及C++STL库的应用
有set,map,map<ll,set>,迭代器的应用
设置
set R;
set::iterator rr;
map<ll, ll> C;
map<ll, set> RC;
map<ll, set>::iterator rc;
R存储row,C存储col,RC存储点<row,col>
(set,map存储均无重复值)
一、
针对add操作
1.map<ll, ll> C:
判断是否出现过col值,有->C[col]++,无->C[col]=1
2.set R:
判断是否出现过row值,无->R.insert(row),有则不做处理
3.map<ll, set> RC:
a.判断RC[row]是否存在,无->RC[row].insert[col]–>操作完成
b.RC[row]存在,判断RC[row]中是否存在col,存在–>操作完成,不存在RC[row].insert[col]
二、
针对remove操作
1.清除RC[row].erase(col)
2.判段RC[row]是否为空,是->R.erase(row)
3.判断C[col]==1是否成立,是->C.erase(col)
三、
针对find操作
1.判断有无最小大于col的值,无->输出-1
2.判断有无最小大于row的值,无->输出-1
3.从upper_bound(row)所对应的RC[row]中,开始找upper_bound(col)
找得到->输出,找不到则再次进行在upper_bound(upper_bound(row))中找upper_bound(col)直到找到或者最后找遍都没有输出-1
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
set<ll> R;
set<ll>::iterator rr;
map<ll, ll> C;
map<ll, set<ll>> RC;
map<ll, set<ll>>::iterator rc;
int main(){
int t = 1, n;
while (~scanf("%d", &n)) {
if (n == 0) break;
if (t != 1) printf("\n");
printf("Case %d:\n", t++);
R.clear();
C.clear();
RC.clear();
char com[10];
int row, col;
while (n--) {
scanf("%s%d%d", com, &row, &col);
if (com[0] == 'a') {
if (C.find(col) == C.end()) C[col] = 1; //判断有无出现过col值
else C[col]++;
if (R.find(row) == R.end()) R.insert(row); //判断有无出现过row值
rc = RC.find(row);
if (rc == RC.end()) RC[row].insert(col); //判断有无出现过row值
else {
rr = rc->second.find(col);
if (rr != rc->second.end()) continue; //判断RC[row]中是否出现过col值
rc->second.insert(col);
}
}
else if (com[0] == 'r') {
RC[row].erase(col);
if (RC[row].empty()) R.erase(row);
if (C[col] == 1) C.erase(col);
}
else if (com[0] == 'f') {
if (C.upper_bound(col) == C.end()) { printf("-1\n"); continue; }
int rrow = row;
while (1) {
rr = R.upper_bound(rrow);
if (rr == R.end()) { printf("-1\n"); break; }
int vr = *rr;
rrow = vr;
rr = RC[vr].upper_bound(col);
if (rr == RC[vr].end()) continue;
else {
printf("%d %d\n", vr, *rr);
break;
}
}
}
}
}
return 0;
}