【A】水题,分奇偶贪心即可。复杂度O(n)
int main()
{
int n;
cin>>n;
if(n%2==0)
{
cout<<n/2<<endl;
for(int i = 0; i < n/2; i++) cout<<"2"<<" ";
}
else{
cout<<n/2<<endl;
for(int i = 0; i < n/2-1; i++) cout<<"2"<<" ";
cout<<"3"<<endl;
}
}
【B】给定3个点,要求另外的点使得这4个点构成平行四边形,暴力枚举计算即可,复杂度O(1)
struct point{
int x, y;
bool operator<(const point &rhs)const{
if(x == rhs.x) return y > rhs.y;
return x < rhs.x;
}
}p[3], ans[10];
int main()
{
int cnt = 0;
cin>>p[0].x>>p[0].y>>p[1].x>>p[1].y>>p[2].x>>p[2].y;
for(int i = 0; i < 3; i++){
for(int j = i + 1; j < 3; j++){
int t = 3 - i - j;
int x = p[i].x - p[j].x;
int y = p[i].y - p[j].y;
ans[cnt++] = point{x + p[t].x , y + p[t].y};
ans[cnt++] = point{p[t].x - x, p[t].y - y};
}
}
sort(ans, ans+cnt);
int t = 1;
for(int i = 1; i < cnt; i++){
if(ans[i].x != ans[i-1].x || ans[i].y != ans[i-1].y){
t++;
}
}
cout<<t<<endl;
cout<<ans[0].x<<" "<<ans[0].y<<endl;
for(int i = 1; i < cnt; i++){
if(ans[i].x != ans[i-1].x || ans[i].y != ans[i-1].y){
cout<<ans[i].x << " "<<ans[i].y<<endl;
}
}
}
【C】给了个由DR组成的字符串,从头开始,每个字母可以干掉和他不同的另外一个字母。到了末尾之后,他又可以到开头,问最后剩下的是哪种字母?贪心+模拟,用set来维护剩余的'D'和'R',然后砍的时候去set里面二分位置,注意细节,没注意找到end之后要变成begin,最后fst了。。复杂度 O(nlogn)
char s[200010];
int vis[200010];
set<int>s1, s2;
map <int, bool> mp;
int main()
{
int n;
cin>>n>>s;
for(int i = 0; i < n; i++){
if(s[i] == 'D') s1.insert(i), mp[i] = 0;
else s2.insert(i), mp[i] = 1;
}
memset(vis, true, sizeof(vis));
while(1)
{
if(s1.empty() || s2.empty()){
break;
}
for(auto & i : mp){
if(s1.empty() || s2.empty()) break;
if(i.second == 0){
auto it = s2.lower_bound(i.first);
if(it == s2.end()) it = s2.begin();
mp.erase(*it);
s2.erase(it);
}
else{
auto it = s1.lower_bound(i.first);
if(it == s1.end()) it = s1.begin();
mp.erase(*it);
s1.erase(it);
}
}
}
if(s1.empty()){
printf("R\n");
}
else{
printf("D\n");
}
}
【D】有许多人参加拍卖,问当假定某些人不参加的时候剩余的人当中谁是最终的赢家,输出他的编号和最终竞价? 解题思路摘抄自 : 点击打开链接 应该是把每个人的所有竞价用set(其他骚东西也行)存储下来,再开一个map将每个人的最高竞价也存下来,然后将该去掉的人去掉后找到那个竞价最高的,这时候切记千万不要直接输出(原因见上面下划线),应该再找到竞价第二高的人的最高竞价x,然后在竞价最高的人的所有竞价里找到一个恰好大于x的一个值。这里还有一个特判,加入将该去的人都去掉以后只剩下一个人了,那么久不会存在竞价第二高的人了,此时应直接输出竞价最高的人的所有竞价中最小的那一个(即他的第一次竞价)
map <int, int> p; //p记录最大
map <int, int > q; //q记录维护的集合
set <int> num[200010]; //记录第一次出现
int b[200010];
int main()
{
int n, qqq;
scanf("%d", &n);
for(int i = 1; i <= n; i++){
int x, y;
scanf("%d%d", &x,&y);
num[x].insert(y);
p[x] = max(p[x], y);
}
for(int i = 1; i <= n; i++)
{
if(p[i])
{
q.insert(MP(p[i], i));
}
}
scanf("%d", &qqq);
for(int i = 1; i <= qqq; i++)
{
int k;
scanf("%d", &k);
for(int j = 1; j <= k; j++){
scanf("%d", &b[j]);
if(p[b[j]]){
q.erase(p[b[j]]);
}
}
int sz = q.size();
if(sz == 0){
printf("0 0\n");
}
else if(sz == 1){
auto it = q.end();
it--;
printf("%d %d\n", it->second, *num[it->second].begin());
}
else{
auto it = q.end();
it--;
int t1 = it -> second;
it--;
int t2 = it -> first;
auto itt = num[t1].upper_bound(t2);
printf("%d %d\n", t1, *itt);
}
for(int j = 1; j <= k; j++){
if(p[b[j]]){
q.insert(MP(p[b[j]], b[j]));
}
}
}
return 0;
}