CF988 DIV3 部分题解

103 阅读8分钟

A.Twice

题意:一个数组内选两个数相消得一分,计算最终得分

思路:用map把相等的存起来,遍历map,ans加上每个值除2


#include<bits/stdc++.h>
using namespace std;
template <typename T, typename U> T ceil(T x, U y) {return (x > 0 ? (x + y - 1) / y : x / y);}
template <typename T, typename U> T floor(T x, U y) {return (x > 0 ? x / y : (x - y + 1) / y);}
#define ll long long
#define ull unsigned long long
#define LL __int128
#define pb push_back
#define ins insert
#define fi first
#define se second
#define all(x) x.begin(),x.end()
typedef pair<ll, ll>PLL;
typedef pair<int, int>PII;
//const ll INF = 5e18;
const ll INF = 0x3f3f3f3f;
const double pi = acos(-1.0);
const int base = 131;
const ll N = 1e6 + 10;
const ll M = 6e6 + 10;
const ll MOD = 1e9 + 7;
const ll mod = 998244353;
const double eps = 0.000001;
priority_queue< ll, vector<ll>, greater<ll> > qq;
bool cmp(int a, int b) { return a > b; }
bool pri(int Su) { if (Su < 2) return false; for (int i = 2; i * i <= Su; i++) { if (Su % i == 0)return false; } return true; }
inline int gcd(int a, int b) { return b > 0 ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
int lowbit(int x) { return x & (-x); }
inline ll max(ll x, ll y) { return x > y ? x : y; }
inline ll min(ll x, ll y) { return x < y ? x : y; }
ll a[N], b[N];
//double a[N], b[N];
//ull ha[N], p[N], Ha[N];
//ull hash_get(int l, int r) { return ha[r] - ha[l - 1] * p[r - l + 1]; }
ll n, m;
//cout << fixed<<setprecision()
int dx[] = { 0, 1 , 0, -1 };
int dy[] = { 1, 0 , -1, 0 };
void ManCity() {
	cin >> n;
	map<ll, ll>mp;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		mp[a[i]]++;
	}
	ll ans = 0;
	for (auto [x, y] : mp) {
		ans += y / 2;
	}
	cout << ans << '\n';
}
int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	int _ = 1;
	cin >> _;
	while (_--) {
		ManCity();
	}
	return 0;
}

B.Intercepted Inputs

题意:给k个数,找两个数n,m满足剩下的数个数等于n*m

思路:确定剩下的数个数一定是k-2个,找一个数能整除(k-2)就确定了一个值,再判断(k-2)/n存不存在就行

#include<bits/stdc++.h>
using namespace std;
template <typename T, typename U> T ceil(T x, U y) {return (x > 0 ? (x + y - 1) / y : x / y);}
template <typename T, typename U> T floor(T x, U y) {return (x > 0 ? x / y : (x - y + 1) / y);}
#define ll long long
#define ull unsigned long long
#define LL __int128
#define pb push_back
#define ins insert
#define fi first
#define se second
#define all(x) x.begin(),x.end()
typedef pair<ll, ll>PLL;
typedef pair<int, int>PII;
//const ll INF = 5e18;
const ll INF = 0x3f3f3f3f;
const double pi = acos(-1.0);
const int base = 131;
const ll N = 1e6 + 10;
const ll M = 6e6 + 10;
const ll MOD = 1e9 + 7;
const ll mod = 998244353;
const double eps = 0.000001;
priority_queue< ll, vector<ll>, greater<ll> > qq;
bool cmp(int a, int b) { return a > b; }
bool pri(int Su) { if (Su < 2) return false; for (int i = 2; i * i <= Su; i++) { if (Su % i == 0)return false; } return true; }
inline int gcd(int a, int b) { return b > 0 ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
int lowbit(int x) { return x & (-x); }
inline ll max(ll x, ll y) { return x > y ? x : y; }
inline ll min(ll x, ll y) { return x < y ? x : y; }
ll a[N];
//double a[N], b[N];
//ull ha[N], p[N], Ha[N];
//ull hash_get(int l, int r) { return ha[r] - ha[l - 1] * p[r - l + 1]; }
ll n, m;
//cout << fixed<<setprecision()
int dx[] = { 0, 1 , 0, -1 };
int dy[] = { 1, 0 , -1, 0 };
void ManCity() {
	cin >> n;
	map<ll, ll>mp;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		mp[a[i]]++;
	}
	ll num = n - 2;
	for (int i = 1; i <= n; i++) {
		if (num % a[i] == 0) {
			if (mp[num / a[i]]) {
				if (num / a[i] == a[i] && mp[a[i]] == 1)continue;
				cout << a[i] << ' ' << num / a[i] << '\n';
				return;
			}
		}
	}
}
int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	int _ = 1;
	cin >> _;
	while (_--) {
		ManCity();
	}
	return 0;
}

C.Superultra's Favorite Permutation

题意:找到一个n的排列满足相邻两个数之和不是质数

思路:大于2的偶数必然不是质数,只要将偶数全放一半,奇数全放一半就能满足,最小不是质数的奇数是9,所奇偶中间用4 5链接

//什么妙妙性质
#include<bits/stdc++.h>
using namespace std;
template <typename T, typename U> T ceil(T x, U y) {return (x > 0 ? (x + y - 1) / y : x / y);}
template <typename T, typename U> T floor(T x, U y) {return (x > 0 ? x / y : (x - y + 1) / y);}
#define ll long long
#define ull unsigned long long
#define LL __int128
#define pb push_back
#define ins insert
#define fi first
#define se second
#define all(x) x.begin(),x.end()
typedef pair<ll, ll>PLL;
typedef pair<int, int>PII;
//const ll INF = 5e18;
const ll INF = 0x3f3f3f3f;
const double pi = acos(-1.0);
const int base = 131;
const ll N = 1e6 + 10;
const ll M = 6e6 + 10;
const ll MOD = 1e9 + 7;
const ll mod = 998244353;
const double eps = 0.000001;
priority_queue< ll, vector<ll>, greater<ll> > qq;
bool cmp(int a, int b) { return a > b; }
bool pri(int Su) { if (Su < 2) return false; for (int i = 2; i * i <= Su; i++) { if (Su % i == 0)return false; } return true; }
inline int gcd(int a, int b) { return b > 0 ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
int lowbit(int x) { return x & (-x); }
inline ll max(ll x, ll y) { return x > y ? x : y; }
inline ll min(ll x, ll y) { return x < y ? x : y; }
ll a[N];
//double a[N], b[N];
//ull ha[N], p[N], Ha[N];
//ull hash_get(int l, int r) { return ha[r] - ha[l - 1] * p[r - l + 1]; }
ll n, m;
//cout << fixed<<setprecision()
int dx[] = { 0, 1 , 0, -1 };
int dy[] = { 1, 0 , -1, 0 };
void ManCity() {
	cin >> n;
	vector<ll>ans;
	if (n < 5) {
		cout << -1 << '\n';
		return;
	}
	for (int i = 2; i <= n; i += 2) {
		if (i != 4)ans.pb(i);
	}
	ans.pb(4);
	ans.pb(5);
	for (int i = 1; i <= n; i += 2) {
		if (i != 5)ans.pb(i);
	}
	for (auto it : ans) {
		cout << it << ' ';
	}
	cout << '\n';
}
int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	int _ = 1;
	cin >> _;
	while (_--) {
		ManCity();
	}
	return 0;
}

D.Sharky Surfing

题意:路上有n个障碍,还有一些提升跳跃距离的装置,问想要到达L至少要捡多少个装置

思路:遍历每个障碍,如果跳跃高度小于这个障碍的长度,将在这个障碍前面的所有装置存进队列,如果这时候队列为空,则直接能判断不能越过这个障碍,否则将装置的数值加上


#include<bits/stdc++.h>
using namespace std;
template <typename T, typename U> T ceil(T x, U y) {return (x > 0 ? (x + y - 1) / y : x / y);}
template <typename T, typename U> T floor(T x, U y) {return (x > 0 ? x / y : (x - y + 1) / y);}
#define ll long long
#define ull unsigned long long
#define LL __int128
#define pb push_back
#define ins insert
#define fi first
#define se second
#define all(x) x.begin(),x.end()
typedef pair<ll, ll>PLL;
typedef pair<int, int>PII;
//const ll INF = 5e18;
const ll INF = 0x3f3f3f3f;
const double pi = acos(-1.0);
const int base = 131;
const ll N = 1e6 + 10;
const ll M = 6e6 + 10;
const ll MOD = 1e9 + 7;
const ll mod = 998244353;
const double eps = 0.000001;
priority_queue< ll, vector<ll>, greater<ll> > qq;
bool cmp(int a, int b) { return a > b; }
bool pri(int Su) { if (Su < 2) return false; for (int i = 2; i * i <= Su; i++) { if (Su % i == 0)return false; } return true; }
inline int gcd(int a, int b) { return b > 0 ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
int lowbit(int x) { return x & (-x); }
inline ll max(ll x, ll y) { return x > y ? x : y; }
inline ll min(ll x, ll y) { return x < y ? x : y; }
ll l[N], r[N], x[N], v[N];
//double a[N], b[N];
//ull ha[N], p[N], Ha[N];
//ull hash_get(int l, int r) { return ha[r] - ha[l - 1] * p[r - l + 1]; }
ll n, m;
//cout << fixed<<setprecision()
int dx[] = { 0, 1 , 0, -1 };
int dy[] = { 1, 0 , -1, 0 };
void ManCity() {
	ll L;
	cin >> n >> m >> L;
	for (int i = 1; i <= n; i++) {
		cin >> l[i] >> r[i];
	}
	priority_queue<ll>q;
	for (int i = 1; i <= m; i++) {
		cin >> x[i] >> v[i];
	}

	ll ans = 0;
	ll cnt = 1;
	ll j = 1;
	for (int i = 1; i <= n; i++) {
		while (cnt < r[i] - l[i] + 2) {
			while (j <= m && x[j] < l[i]) {
				q.push(v[j]);
				j++;
			}
			if (q.empty()) {
				cout << -1 << '\n';
				return;
			}
			cnt += q.top();
			ans++;
			q.pop();
		}
	}
	cout << ans << '\n';
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	int _ = 1;
	cin >> _;
	while (_--) {
		ManCity();
	}
	return 0;
}

E.Kachina's Favorite Binary String

题意:有一个字符串,每次询问l,r,回复这个区间内有多少个子序列是01的,最多询问n次,能否求得完整的字符串

思路:从1到n每次询问[1,i],如果回复值x大于0则确定i位置上一定是1,再通过回复值x可以判断i前面是i-x-1个1后跟着若干个0,再从i+1继续询问,如果当前回复值x大于上一次询问的值,则当前i位置为1,否则为0

#include<bits/stdc++.h>
using namespace std;
template <typename T, typename U> T ceil(T x, U y) {return (x > 0 ? (x + y - 1) / y : x / y);}
template <typename T, typename U> T floor(T x, U y) {return (x > 0 ? x / y : (x - y + 1) / y);}
#define ll long long
#define ull unsigned long long
#define LL __int128
#define pb push_back
#define ins insert
#define fi first
#define se second
#define all(x) x.begin(),x.end()
typedef pair<ll, ll>PLL;
typedef pair<int, int>PII;
//const ll INF = 5e18;
const ll INF = 0x3f3f3f3f;
const double pi = acos(-1.0);
const int base = 131;
const ll N = 1e6 + 10;
const ll M = 6e6 + 10;
const ll MOD = 1e9 + 7;
const ll mod = 998244353;
const double eps = 0.000001;
priority_queue< ll, vector<ll>, greater<ll> > qq;
bool cmp(int a, int b) { return a > b; }
bool pri(int Su) { if (Su < 2) return false; for (int i = 2; i * i <= Su; i++) { if (Su % i == 0)return false; } return true; }
inline int gcd(int a, int b) { return b > 0 ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
int lowbit(int x) { return x & (-x); }
inline ll max(ll x, ll y) { return x > y ? x : y; }
inline ll min(ll x, ll y) { return x < y ? x : y; }
ll a[N];
//double a[N], b[N];
//ull ha[N], p[N], Ha[N];
//ull hash_get(int l, int r) { return ha[r] - ha[l - 1] * p[r - l + 1]; }
ll n, m;
//cout << fixed<<setprecision()
int dx[] = { 0, 1 , 0, -1 };
int dy[] = { 1, 0 , -1, 0 };
void ManCity() {
    cin>>n;
    string s="";

    ll f=0,x;
    ll cnt=0;
    bool flag=false,ff=false;
    for(int i=2;i<=n;i++){
    	cout<<"? "<<1<<' '<<i<<endl;
    	ll x;
    	cin>>x;
    	if(x){
    		f=i;
    		cnt=x;
    		if(f==n){
    			flag=true;
    			f=x;

    		}
    		ff=true;
    		break;
    	}
    }
    if(!ff){
    	cout<<"! IMPOSSIBLE"<<endl;
    	return;
    }
    if(flag){
    	if(f==n-1){
    		for(int i=1;i<n;i++){
    			s+="0";
    		}
    		s+="1";
    		cout<<"! "<<s<<endl;
    		return;
    	}
    	for(int i=1;i<n-f;i++){
    		s+="1";
    	}
    	for(int i=n-f;i<n;i++){
    		s+="0";
    	}
    	s+="1";
    	cout<<"! "<<s<<endl;
    	return;
    }
    for(int i=1;i<f-cnt;i++){
    	s+="1";
    }
    for(int i=f-cnt;i<f;i++){
    	s+="0";
    }
    s+="1";
    cnt=x;
    for(int i=f+1;i<=n;i++){
    	cout<<"? "<<1<<' '<<i<<endl;
    	cin>>x;
    	if(x>cnt)s+="1";
    	else s+="0";
    	cnt=x;
    }
    cout<<"! "<<s<<endl;
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int _ = 1;
    cin >> _;
    while (_--) {
        ManCity();
    }
    return 0;
}