码迷,mamicode.com
首页 > 其他好文 > 详细

20/07/23

时间:2020-07-23 23:30:31      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:for   连续   class   line   name   滚动   ons   min   mod   

T1

数学问题,考试时没yy出公式,用滚动数组瞎搞了一个\(50\)%的暴力。

暴力代码找不见了,贴正解吧。

#include <bits/stdc++.h>
using namespace std;

const int mod = 998244353;

#define ll long long

int t;

ll fast(ll a, ll b){
	ll ans = 1;
	while(b){
		if(b&1) ans = (ans*a)%mod;
		a = (a*a)%mod;
		b >>= 1;
	}
	return ans%mod;
}

signed main(){
	scanf("%d", &t);
	for(ll n; t; t --){
		scanf("%lld", &n);
		if(n == 1){
			printf("%d\n", 1);
			continue;
		}
		printf("%lld\n", ((fast(2,n-2)%mod)*((n-1)%mod)+(fast(2,n-1))%mod)%mod);
	}
	return 0;
}

这里注意快速幂无法处理类似这样的情况\(a=1,b=-1\),这个不难读者自证,所以在\(n==1\)的时候特判一下。

T2

正解贪心。不会。

发现在百分之六十的数据范围内有特殊性质。考试时上厕所的时候灵光一现想出来的。真的这是真的!

STL非常好写。

考场代码:

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e6+10;

int n, ans = 1<<29, vis[maxn];

set<int> v[maxn];
queue<int> q;

signed main(){
	scanf("%d", &n);
	for(int i = 1, x, y; i <= n; i ++){
		scanf("%d%d", &x, &y);
		if(!vis[x]){
			vis[x] = 1;
			q.push(x);
		}
		v[x].insert(y); 
	}
	while(q.size()){
		int now = q.front(), tmp;
		q.pop();
		tmp = n - v[now].size();
		ans = min(ans, tmp);
	}
	printf("%d", ans);
	return 0;
}

正解:

自己考场时发现的性质:

\(60\)%的数据中,\(b_i \leq n\),想要组成同花顺必须让所有的牌数字连续,故此时在\(n\)张牌中的\(b_i\)一定为\(1\)\(n\)中的每一个数。

此时用\(n\)减去每一种花色去重之后的数量即是以这种花色的牌为同花顺需翻的牌数。最后取\(min\)即可。

其实已经很接近正解了。

我们求出当前牌中可留下的最大长度的牌即可。用\(n\)减去这个最大长度即为答案。

代码:

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e6+10;

int n, cnt, ans;
pair<int,int>a[maxn], b[maxn];

bool cmp(pair<int,int> x, pair<int,int> y){
	if(x.first == y.first) return x.second < y.second;
	return x.first < y.first;
}

signed main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++){
		scanf("%d%d", &a[i].first, &a[i].second);
	}
	sort(a+1, a+n+1, cmp);
	for(int i = 1; i <= n; i ++){
		if(a[i].second == a[i-1].second and a[i].first == a[i-1].first) continue;
		++cnt;
		b[cnt].first = a[i].first, b[cnt].second = a[i].second;
	}
	for(int i = 1; i <= cnt; i ++){
		int tmp = 0;
		for(int j = i; j >= 1; j --){
			if(b[i].first == b[j].first and b[i].second-b[j].second+1 <= n) ++ tmp;
			else break;
		}
		ans = max(ans, tmp);
	}
	printf("%d", n-ans);
	return 0;
}

T3

数据结构题。正解为二分答案+线段树检查是否合法。不会

直接暴力sort。考试的时候脑抽加了一个脑抽特判导致爆零。本来还以为能跑快一点呢qaq。

考场代码:

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5+10;

int i, n, m, p, a[maxn], l[maxn], r[maxn], opt[maxn];

bool cmp(int a, int b){return a > b;}

signed main(){
	scanf("%d%d", &n, &m);
	for(i = 1; i <= n; ++ i){
		scanf("%d", &a[i]);
	}
	for(i = 1; i <= m; ++ i){
		scanf("%d%d%d", &opt[i], &l[i], &r[i]);
	}
	scanf("%d", &p);
	for(i = 1; i <= m; ++ i){
		if(opt[i]) sort(a+l[i]+1, a+r[i]+1, cmp);
		else sort(a+l[i]+1, a+r[i]+1);
	}
	printf("%d", a[p]);
	return 0;
}

正解:

啊不想写了先咕着qwq

20/07/23

标签:for   连续   class   line   name   滚动   ons   min   mod   

原文地址:https://www.cnblogs.com/Vanyun/p/13368474.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!