2021 Xinjiang Provincial Collegiate Programming Contest

K题:

签到题,按题目意思模拟即可。

ac代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6;;
void memcpy(string s,int p1,int p2,int l) {
	p1 --;p2 --;
	for(int i = 0; i < l; i ++) {
		s[p2 + i] = s[p1 + i];
	}
	cout<<s<<endl;
}
void memmove(string s,int p1,int p2,int l) {
	p1 --;p2 --;
	string tmp = s;
	for(int i = 0; i < l; i ++) {
		s[p2 + i] = tmp[p1 + i];
	}
	cout<<s<<endl;
}
void slove() {
	int n,p1,p2,l;
	string s;
	cin>>n>>s>>p1>>p2>>l;
	memcpy(s,p1,p2,l);
	memmove(s,p1,p2,l);
}
int main() {
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	slove();
	return 0;
}

E题:

贪心,找价格最大的连续递减序列,模拟。

ac代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6;
struct node {
	ll pri;
	bool f;
	ll day;
	node(ll a,ll b,bool c) {
		pri = a;
		day = b;
		f = c;
	}
	bool operator <(const node &x) {
		if(pri == x.pri) return day < x.day;
		return pri > x.pri;
	}
};
ll mi[N];
vector<node> v;
int main() {
	int n;
	cin>>n;
	for(int i = 1; i <= n; i ++) {
		int a,b;
		cin>>a>>b;
		mi[i] = min(a,b);
		if(a <= b) {
			v.push_back(node(b,i,1));
		}
		else 
			v.push_back(node(a,i,0));
	}
	sort(v.begin(),v.end());
	ll lastday = 0;
	ll cost = 0,cnt = 0;
	ll ans = 0;
	for(auto it : v) {
		int day = it.day;
		if(day < lastday) continue;
		int pri = it.pri;
		if(cnt != 0 && cost >= pri) {
			cost = 0;
			cnt = 0;
		}
		for(int i = lastday + 1; i < day; i ++) {
			if(mi[i] < pri) {
				cnt ++;
				cost += mi[i];
			}
		}
		if(it.f) {
			cnt ++;
			cost += mi[day];
			ans += (cnt * pri - cost);
			cost = 0;
			cnt = 0;
		}
		else {
			ans += (cnt * pri - cost);
			cnt = 1;
			cost = mi[day];
		}
		lastday = day;
	}
	cout<<ans;
}

J题:

签到题,dp[i] 表示以数字 i 结尾的链的最小值。

ac代码:

#include<bits/stdc++.h> 
using namespace std;
const int N = 1e6 + 5;
int dp[N + 1][2],cnt[N + 1],n,ans;
int main() {
	ios::sync_with_stdio(0);
	cin>>n;
	while(n --) {
		int x;
		cin>>x;
		cnt[x] ++;
	}
	for(int i = 1; i <= N; i ++) {
		if(i&1)
			dp[i][0] = cnt[i];
		else {
			dp[i][0] = min(dp[i / 2][0],dp[i / 2][1]) + cnt[i];
			dp[i][1] = dp[i/2][0];
		}
	}
	for(int i = N / 2 + 1; i <= N; i ++) {
		ans += min(dp[i][0],dp[i][1]);
	}
	cout<<ans;
	return 0;
}

I题:

思路:考虑二分查找,注意对正负分类讨论。

ac代码:

#include<bits/stdc++.h> 
#define ll long long
using namespace std;
const int N = 1e6 + 5;
ll n,m,l,r,ans;
double a[N],b[N];
void slove() {
	cin>>n>>m;
	for(int i = 0; i < n; i ++) cin>>a[i];
	for(int i = 0; i < m; i ++) cin>>b[i];
	cin>>l>>r;
	sort(a,a+n);
	sort(b,b+m);
	for(int i = 0; i < n; i ++) {
		if(a[i] == 0) {
			if(l <= 0 && r >= 0) ans += m;
		}
		else if(a[i] > 0) {
			int L = lower_bound(b,b+m,l/a[i]) - b;
			if(L == m) continue;
			int R = upper_bound(b,b+m,r/a[i]) - b;
			ans += R - L;
		}
		else {
			int L = lower_bound(b,b+m,r/a[i]) - b;
			if(L == m) continue;
			int R = upper_bound(b,b+m,l/a[i]) - b;
			ans += R - L;
		}
	}
	cout<<ans;
}
int main() {
	ios::sync_with_stdio(0);
	slove(); 
	return 0;
}

G题:

思路:签到题,找规律。

ac代码:

#include<bits/stdc++.h> 
#define ll long long
using namespace std;
const int N = 200;
ll t,n,m,k;
void slove() {
	cin>>t;
	while(t --) {
		cin>>n>>m>>k;
		ll ans = k / n; 
		if(ans & 1) {
			ans = ans + n - k % n - 1;
		}
		else {
			ans = ans + k % n;
		}
		cout<<ans<<endl;
	}
}
int main() {
	ios::sync_with_stdio(0);
	slove(); 
	return 0;
}

F题:

思路:小球多次碰撞后彼此相对位置不变,还有末尾不能多空格。

ac代码:

#include<bits/stdc++.h> 
#define ll long long
using namespace std;
const int N = 1e5 + 5;
ll k,n;
struct node {
	int pos;
	int v;
	int id;
}a[N];
int idx[N];
bool cmp(node a,node b) {
	return a.pos < b.pos;
}
void slove() {
	cin>>n>>k;
	for(int i = 0; i < n; i ++) {
		cin>>a[i].pos>>a[i].v;
		a[i].id = i;
	}
	sort(a,a+n,cmp);
	for(int i = 0; i < n; i ++) {
		idx[a[i].id] = i;
		a[i].pos += k * a[i].v;
	}
	sort(a,a+n,cmp);
	for(int i = 0; i < n; i ++) {
        if(i == n - 1) cout<<a[idx[i]].pos;
        else cout<<a[idx[i]].pos<<" ";
	}
}
int main() {
	ios::sync_with_stdio(0);
	slove(); 
	return 0;
}

D题:

思路:分三种情况,l=r分组排序;n >= 2 * n,全排列; n < 2 * n 两段排列,中间不排。

ac代码:

#include<bits/stdc++.h> 
#define ll long long
using namespace std;
const int N = 1e5 + 5;
int n, l, r, cnt;
string str, tmp;
void slove() {
    cin>>n>>l>>r>>str;
    if (l == r) {
        for (int i = 0; i < l; i++) {
            tmp.clear();
            cnt = 0;
            for (int j = i; j < n; j += l)
                tmp += str[j];
            sort(tmp.begin(), tmp.end());
            for (int j = i; j < n; j += l)
                str[j] = tmp[cnt++];
        }
    }
    else if (n < l + l) {
        for (int i = 0; i < n; i++) {
            if (i >= l || i < n - l)
                tmp += str[i];
        }
        sort(tmp.begin(), tmp.end());
        for (int i = 0; i < n; i++) {
            if (i >= l || i < n - l)
                str[i] = tmp[cnt++];
        }
    }
    else
        sort(str.begin(), str.end());
    cout<<str;
}
int main() {
	ios::sync_with_stdio(0);
	slove(); 
	return 0;
}

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值