A:思维题,观察后很容易发现
最难猜的情况是所有点都被电脑选定了(也就是不会提供额外信息)
所以以下的所有分析都是基于所有点都是可疑点
当n==1&&m==1
,显然不需要探测就能知道目标点在哪
当n==1||m==1
我们只需要探测这一条线上的一段,即可得知目标点
其他情况:均为2,只需要将两个点放在矩形的左上角与右下角,此时两圆相接确定一个点
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n, m;
void solve() {
cin >> n >> m;
if (n > m)
swap(n, m);
if (n == 1 && m == 1) {
cout << "0" << endl;
return;
}
if (n == 1 ) {
cout << "1" << endl;
return;
} else {
cout << "2" << endl;
return;
}
}
signed main() {
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--)
solve();
}
B:假设要删数字X,易知,删除部分X对答案的影响等价于删除全部X对答案的影响。(如果只删除部分,如果剩下的字符串是回文的,剩下的X也会互相配对----等价于没有)
所以只需要从两端往中间搜,找到第一个冲突点A,B.分裂出剔除掉A或B两种情况,只要其中一个情况合法,即可行
#include <bits/stdc++.h>
#define long long
#define endl '\n'
using namespace std;
int n, m;
const int N = 2e5 + 10;
int a[N];
vector<int>g1, g2;
int tag1 = 0, tag2 = 0;
bool check1() {
for (int i = 1; i <= n; i++) {
if (a[i] != a[n - i + 1]) {
tag1 = a[i];
tag2 = a[n - i + 1];
return false;
}
}
return true;
}
bool check2() {
int l = g1.size() - 1;
int l2 = g2.size() - 1;
int ok = 0;
for (int i = 1; i <= l; i++) {
if (g1[i] != g1[l + 1 - i]) {
ok = 1;
break;
}
}
if (!ok) {
return true;
}
ok = 0;
for (int i = 1; i <= l2; i++) {
if (g2[i] != g2[l2 + 1 - i ]) {
ok = 1;
break;
}
}
if (!ok) {
return true;
}
return false;
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
if (check1()) {
cout << "YES" << endl;
return;
}
g1.clear();
g2.clear();
g1.push_back(0);
g2.push_back(0);
for (int i = 1; i <= n; i++) {
if (a[i] != tag1) {
g1.push_back(a[i]);
}
if (a[i] != tag2) {
g2.push_back(a[i]);
}
}
if (check2()) {
cout << "YES" << endl;
} else {
cout << "NO" << endl;
}
}
signed main() {
int t;
cin >> t;
while (t--)
solve();
}
C:使用useful algorithm(二分)
二分邀请的人数,在check中
设x为还需要邀请多少人才能满足条件
设have为已经邀请了多少人
如果第i个人的a[i].a >= x - 1 && a[i].b >= have
那么就选择他,并且x–,have++
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, m;
const int N = 2e5 + 10;
struct node {
int a, b;
} a[N];
bool check(int x) {
int sum = x;
int have = 0;
for (int i = 1; i <= n; i++) {
if (a[i].a >= x - 1 && a[i].b >= have) {
x--;
have++;
}
if (have == sum)
return true;
}
return false;
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i].a >> a[i].b;
}
int l = 1, r = n ;
int pre = 1e9;
while (l < r) {
int mid = l + r + 1 >> 1;
if (check(mid)) {
//cout << "true" << endl;
l = mid ;
} else {
//cout << "false" << endl;
r = mid - 1;
}
}
cout << l << endl;
}
signed main() {
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--)
solve();
}