Codeforces Round #803 (Div. 2)

题目链接

A

水题

// Problem: A. XOR Mixup
// Contest: Codeforces - Codeforces Round #803 (Div. 2)
// URL: https://codeforces.com/contest/1698/problem/A?mobile=true
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define NO {puts("NO") ; return ;}
#define YES {puts("YES") ; return ;}
#define endl "\n"
#define int long long 


const int N=1e3+10;

int a[N];

void solve()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>a[i];
	sort(a+1,a+1+n);
	cout<<a[(n+1)/2]<<endl;
	return;
	
	
	
}

signed main()
{
int T;
cin>>T;
while(T--)
{
	solve();
}
}

B

核心思路

分析当我们想要使一个堆变为"tall"该怎么办呢,我们可以通过模拟发现当我们的k大于2的时候是不可能把这个堆变为"tall".只有k=1的时候才有可能。

// Problem: B. Rising Sand
// Contest: Codeforces - Codeforces Round #803 (Div. 2)
// URL: https://codeforces.com/contest/1698/problem/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define NO {puts("NO") ; return ;}
#define YES {puts("YES") ; return ;}
#define endl "\n"
#define int long long 


const int N=1e6+10;

int a[N];

void solve()
{
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++)
	cin>>a[i];
	if(k==1)
	{
		if(n%2)
		cout<<n/2<<endl;
		else
		cout<<n/2-1<<endl;
	}
	else
	{
		int cnt=0;
		for(int i=2;i<=n-1;i++)
		{
			if(a[i]>a[i-1]+a[i+1])
			cnt++;
		}
		cout<<cnt<<endl;
	}
}

signed main()
{
int T;
cin>>T;
while(T--)
{
	solve();
}

return 0;
}

C

核心思路

照样使那个思路,想考虑特殊点或者使先从很小的一个方面入手,看可不可以分析出来相关性质。

首先我们可以考虑0这个特殊的点。

  1. 1 0 0 0.....这个只包含一个正整数或者是负数,其他都是0的肯定是可行的。
  2. 1 -1 0 0 0....这种由x和-x组成的肯定也是可以的。
  3. 我们可以思考如果由三个正整数或者是三个负整数可以吗,答案是显然不可以的,因为不可能有数可以等于三个正整数的和,假设存在x=i+j+k,那么x+j+k又有谁可以和他们划等号呢。

当我们把这个性质分析出来了,时间复杂度就是O(1)的了,因为最多也就只有5个数了,也就是2个正数和2个负数还有个0.

// Problem: C. 3SUM Closure
// Contest: Codeforces - Codeforces Round #803 (Div. 2)
// URL: https://codeforces.com/contest/1698/problem/C
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define NO {puts("NO") ; return ;}
#define YES {puts("YES") ; return ;}
#define endl "\n"
#define int long long 

int n;

const int N=1e6+10;

int a[N];
int erfen(int x)
{
	int l=1;
	int r=n;
	while(l<r)
	{
		int mid=l+r>>1;
		if(a[mid]>=x)
		r=mid;
		else
		l=mid+1;
	}
	return l;
}

void solve()
{
	cin>>n;
	
	int flag=1,cnt0=0,cnt1=0,cnt2=0;
	unordered_map<int ,int> mp;
	vector<int> b;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
		mp[a[i]]++;
	}
	for(int i=0;i<n;i++)
	{
		if(a[i]==0)
		{
			cnt0++;
		}
		else if(a[i]>0)
		{
			cnt1++;
			b.push_back(a[i]);
		}
		else
		{
			cnt2++;
			b.push_back(a[i]);
		}
	}
	if(cnt1>2||cnt2>2)
	{
		NO;
	}	
	if(cnt0)
	b.push_back(0);
	int l=b.size();
	for(int i=0;i<l;i++)
	{
		for(int j=i+1;j<l;j++)
		{
			for(int k=j+1;k<l;k++)
			{
				if(mp[b[i]+b[j]+b[k]]==0)
				{
					flag=0;
				}
			}
		}
	}
	if(flag)
	{
		YES;
	}
	else
	{
		NO;
	}
	
	
}

signed main()
{
	
	int T;
	cin>>T;
	while(T--)
	{
		solve();
	}

}

D

核心思路

首先根据数据范围知道这个肯定是二分。

然后分析样例来挖掘性质

样例: 4 2 1 3 5
实际: 1 2 3 4 5
我们分析区间[3,5],我们发现如果是在区间里面的数交换那么我们次数一定成对增加。
也就是发现了一个重要的性质那就是:如果在内部的交换次数是一个奇数,那么就说明有一个元素的位置没有交换。
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
#define int long long 
const int N = 2e5 + 10;
int n, a[N];

void solve()
{
    cin >> n;
    int l = 1, r = n , cnt = 0;
    while(l < r)
    {
        int mid = l + r >> 1;
        cout << "? " << l << " " << mid << endl;
        for(int i = l ; i <= mid ; i ++ ) cin >> a[i];
        cnt = 0;
        for(int i = l ; i <= mid ; i ++ )
            if(a[i] >= l && a[i] <= mid) cnt ++ ;
        if(cnt & 1) r = mid; // 在区间内 缩小区间
        else l = mid + 1; // 在另一个区间
    }
    cout << "! " << l << endl;
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0);
    int T;
    cin >> T;
    while(T -- ) solve();
    return 0;
}
posted @ 2023-01-20 23:44  努力的德华  阅读(37)  评论(0)    收藏  举报