


你站在0,0的位置上,你可以往上,下,左,右,四个方向走。这片区域有n个箱子,位于(xi,yi),你需要走到(xi,yi)才能捡起箱子,问你从(0,0)捡完所有箱子再回到(0,0)需要几步
我们只需求出最左/右边箱子的横坐标,最上/下边箱子的纵坐标。这就是我们四个方向要走的最大距离,然后把四个数的绝对值乘2累加即可
- #include
- using namespace std;
-
-
- int main(){
- int t;
- cin >> t;
- while(t--){
- int n;
- cin >> n;
- int a = 105;
- int b = 105;
- int c = -105;
- int d = -105;
- for(int i = 0; i < n; i++){
- int x, y;
- cin >> x >> y;
- if(x < 0){
- a = min(a, x);
- }else{
- c = max(c, x);
- }
- if(y < 0){
- b = min(b, y);
- }else{
- d = max(d, y);
- }
- }
- int ans = 0;
- if(a != 105){
- ans += abs(a) * 2;
- }
- if(b != 105){
- ans += abs(b) * 2;
- }
- if(c != -105){
- ans += c * 2;
- }
- if(d != -105){
- ans += d * 2;
- }
- cout << ans << endl;
- }
- return 0;
- }

题意:你可以对一个数组进行操作:
1.选择两个索引l,r
2.将a[l] ~ a[r]的所有数-1。
f(a)表示把数组a的所有数变成0的操作数
现在规定一种数组B是a数组进行重新排列后的新数组
问是否所有满足条件的B数组f(B)>= f(a)
f(B)最小的B数组一定是一个满足Bi+1 >= Bi 或者 Bi+1 <= Bi的数组,那么如果a数组不满足的话,就会有f(B) < f(a)
- #include
- using namespace std;
-
- int a[100005];
-
- int main(){
- int t;
- cin >> t;
- while(t--){
- int n;
- cin >> n;
- for(int i = 0; i < n; i++){
- cin >> a[i];
- }
- bool f = 0;
- bool ff = 0;
- for(int i = 1; i < n - 1; i++){
- if(a[i] < a[i - 1]){
- f = 1;
- }
- if(f && a[i] < a[i + 1]){
- ff = 1;
- break;
- }
- }
- if(ff){
- cout << "NO" << endl;
- }else{
- cout << "YES" << endl;
- }
- }
- return 0;
- }

有个数组a是0~n-1的排列的一种,如果ai + i是平方数,那么这个数组是好的,现在需要构造出a数组
我们可以把1e5内的所有完全平方数求出来,从(n-1)遍历到0,求出每个数能放的位置,(越大的数能放的位置越少)我们先把大的数放了,那么小的数能放的位置也会逐渐减少。我们遍历结束了a数组也就出来了
- #include
- using namespace std;
-
- int arr[100005];
-
- int main(){
- int t;
- cin >> t;
- while(t--){
- int n;
- cin >> n;
- for(int i = 0; i < n; i++){
- arr[i] = -1;
- }
- vector<int> ve;
- for(int i = 0; i * i < n; i++){
- ve.push_back(i * i);
- if((i + 1) * (i + 1) >= n){
- ve.push_back((i + 1) * (i + 1));
- }
- }
- int m = ve.size() - 1;
- for(int i = n - 1; i >= 0; i--){
- for(int j = m; j >= 0; j--){
- if(ve[j] - i < n && arr[ve[j] - i] == -1){
- arr[ve[j] - i] = i;
- break;
- }
- }
- }
- for(int i = 0; i < n; i++){
- cout << arr[i] << " ";
- }
- cout << endl;
- }
- return 0;
- }




这是一个交互问题。
有一场由2n名选手组成的锦标赛。第一名选手与第二名选手竞争,第三名选手与第四名选手竞争,以此类推。之后,第一场比赛的获胜者与第二场比赛的获胜者进行竞争,依此类推。锦标赛结束时,只剩下一名选手,他被宣布为锦标赛的获胜者。这样的锦标赛方案被称为单淘汰赛。
你不知道结果,但你想找出锦标赛的获胜者。在一个查询中,您选择两个整数a和b,它们是两个参赛者的索引。如果A比B赢了更多的比赛,评审团将返回1,如果B比A赢了更多的比赛,评审团将返回2,如果他们的胜利数量相等,评审团将返回0。
在不超过⌈13个⋅2n+1个⌉查询中找到赢家。这里,⌈x⌉表示向上舍入到最接近的整数的x的值。
请注意,锦标赛已经结束很久了,这意味着结果是固定的,不依赖于您的查询。
我们需要在2 ^ (n+1)/3次查询内得出正确答案,所以如果有4个人我们需要在2次查询内得到谁是胜者:
有a,b,c,d四个人,我们先查询a,c
如果a > c,那么就说明d是c,d的迎着,我们再次查询a,d即可
如果a < c,那么我们查询b, c即可
如果a == c,那么两个人在第一轮都是输的一方,那么查询b, d,即可
如果剩下两人,我们需要查询这两人
直到只剩下一人就可以确定冠军了
- #include
- using namespace std;
-
- int ask(int a, int b){
- cout << "? " << a << " " << b << endl;
- cout.flush();
- int ans;
- cin >> ans;
- return ans;
- }
-
- int main(){
- int t;
- cin >> t;
- while(t--){
- int n;
- cin >> n;
- queue<int> q;
- int m = pow(2, n);
- for(int i = 1; i <= m; i++){
- q.push(i);
- }
- while(q.size() >= 4){
- int a = q.front();
- q.pop();
- int b = q.front();
- q.pop();
- int c = q.front();
- q.pop();
- int d = q.front();
- q.pop();
- int ans = ask(a, c);
- int x;
- if(ans == 2){
- ans = ask(b, c);
- if(ans == 2){
- x = c;
- }else{
- x = b;
- }
- }else if(ans == 1){
- ans = ask(a, d);
- if(ans == 1){
- x = a;
- }else{
- x = d;
- }
- }else{
- ans = ask(b, d);
- if(ans == 1){
- x = b;
- }else{
- x = d;
- }
- }
- q.push(x);
- }
- if(q.size() == 2){
- int a = q.front();
- q.pop();
- int b = q.front();
- q.pop();
- int ans = ask(a, b);
- if(ans == 1){
- q.push(a);
- }else{
- q.push(b);
- }
- }
- if(q.size() == 1){
- cout << "! " << q.front() << endl;
- cout.flush();
- }
- }
- return 0;
- }