Gym102091,第四场训练赛

Gym102091
比赛时只写了CDGHJL

C

对二元组 ( a i , i ) (a_i, i) (ai,i) a i a_i ai 为第一关键字, i i i 为第二关键字升序排列,求最长的序列使得对任意 i , j i, j i,j ∣ i − j ∣ ≤ w |i-j| \leq w ijw
直接dp即可,时间复杂度 O ( n 2 ) O(n^2) O(n2)

int n, w;
struct Node {
	int a, idx, cnt;
	bool operator < (const Node &x) const {
		return a < x.a;
	}
}node[maxn];
void solve() {
    cin >> n >> w;
    for(int i = 1; i <= n; i++) {
    	cin >> node[i].a;
    	node[i].idx = i;
    }
    sort(node + 1, node + n + 1);
    int ans = 0;
    for(int i = 1; i <= n; i++) {
    	for(int j = 1; j < i; j++) {
    		if(abs(node[j].idx - node[i].idx) <= w && node[i].a > node[j].a) {
    			node[i].cnt = max(node[i].cnt, node[j].cnt + 1);
    			ans = max(ans, node[i].cnt);
    		}
    	}
    }
    cout << ans << endl;
}

D

签到,贪心即可

int n;
int a[maxn];
void solve() {
    cin >> n;
    if(n == 0) {
    	cout << 0 << endl;
    	return;
    }
    for(int i = 1; i <= n; i++) cin >> a[i];
    int cnt = 1;
    int p = a[1] + 10;
    for(int i = 1; i <= n; i++) {
    	if(a[i] > p + 10) {
    		cnt++;
    		p = a[i] + 10;
    	}
    }
    cout << cnt << endl;
}

G

强连通分量板子,队友写的

vector<int> vec[205];
int dfn[205],low[205];
int cnt=0;
int s[205],scc[205];
int tmp=0,num=0;
void tarjan(int x){
	dfn[x]=low[x]=++cnt;
	s[++tmp]=x;
	for(int i=0;i<vec[x].size();i++)
	{
		int u=vec[x][i];
		if(!dfn[u]){
			tarjan(u);
			low[x]=min(low[x],low[u]);
		}else if(!scc[u]){
			low[x]=min(low[x],dfn[u]);
		}
	}
	
	if(dfn[x]==low[x]){
		num++;
		while(tmp){
			int p=s[tmp--];
			scc[p]=num;
			if(p==x)break;
		}
	}
}
void solve() {
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)vec[i].clear();
    for(int i=1;i<=m;i++)
    {
    	int u,v;
    	cin>>u>>v;
    	u++,v++;
    	vec[u].push_back(v);
    }
	memset(dfn,0,sizeof(dfn));
	memset(low,0,sizeof(low));
	memset(s,0,sizeof(s));
	memset(scc,0,sizeof(scc));
	cnt=0,tmp=0,num=0;
	for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
    cout<<num<<'\n';
}

H

题意

给出 a , b , c a, b, c a,b,c x 3   m o d   a , x 3   m o d   b , x 3   m o d   c x^3\ mod\ a,x^3\ mod\ b, x^3\ mod\ c x3 mod a,x3 mod b,x3 mod c 的值,求 x x x 其中 a , b , c < 2 21 a, b, c < 2^{21} a,b,c<221
不知道正解怎么做的,直接从 1 到 2 21 2^{21} 221 枚举 x,满足上面三个式子即是答案。不知道为什么x一定在这个范围内。

LL exgcd(LL a, LL b, LL &x, LL &y) {
    if(!b) {x = 1; y = 0; return a;}
    LL d = exgcd(b, a%b, x, y);
    LL z = x; x = y; y = z - y * (a / b);
    return d;
}
ll inv(ll a, ll p) {
    ll x, y;
    exgcd(a, p, x, y);
    return (x % p + p) % p;
}
ll mul(ll a, ll b, ll p) {
    LL ans = 0;
    a %= p;
    for (; b; b >>= 1) {
        if (b & 1)  ans = (ans + a) % p;
        a = (a + a) % p;
    }
    return ans;
}
ll M;
ll excrt(ll m[], ll a[], ll n)
{
    M=m[1];
    ll ans=a[1];
    for(int i=2;i<=n;++i)
    {
        ll k1,k2,g=exgcd(M,m[i],k1,k2);
        if((a[i]-ans)%g)return -1;	//判断是否无解
        k1=(a[i]-ans)/g*k1%m[i];
        ans+=k1*M;
        M=M/g*m[i];
        ans%=M;
    }
    return (ans-1+M)%M+1;
}
void solve() {
    ll a[5];
    ll b[5];
    for(int i = 1; i <= 3; i++) cin >> a[i];
    for(int i = 1; i <= 3; i++) cin >> b[i];
    ll ans = excrt(a, b, 3);
    int mx = (1 << 21);
	for(int i = 1; i <= mx; i++) {
		int now = i * i * i;
		if(now - ans < 0) continue;
		if((now - ans) % M == 0) {
			cout << i << endl;
			break;
		}
	}
}

J

题意

在这里插入图片描述
就是给出 l o w , h i g h low,high low,high ,求这个式子的值,但题目明确表示直接模拟会有精度问题。
队友写了几分钟直接秒了orz,实际上就是求导。
在这里插入图片描述

#include <bits/stdc++.h>

#define int long long

using namespace std;

typedef long double ld;

signed main()
{
#ifdef DDD
	freopen("input.txt", "r", stdin);
#endif
	ios::sync_with_stdio(false);
	cin.tie(0);	cout.tie(0);
	ld x, y;
	while (cin >> x >> y && !(x==0&&y==0))
	{
		ld ans = 0.;
		for (ld i=x; i<=y; ++i)
		{
			ld tmp;
			tmp = pow(i, -(ld)2.0/3.0);
			ans += tmp;
		}
		ans /= 3.0;
		ans *= 1e-15;
		string line, line2;
		stringstream ss(line2);
		ss << setprecision(5) << scientific;
		ss << ans;
		ss >> line;
		line[7] = 'E';
		if (line.size() == 10)
		{
			line = line + line[9];
			line = line + line[9];
			line[9] = '0';
			line[10] = '0';
		}
		else if (line.size() == 11)
		{
			line = line + line[10];
			line[10] = line[9];
			line[9] = '0';
		}
		else
		{
			line[9] = line[line.size()-3];
			line[10] = line[line.size()-2];
			line[11] = line[line.size()-1];
			line = line.substr(0, 12);
		}
		cout << line << '\n';
	}
    return 0;
}

L

题意

给出只包含0,1的 n 行 m 列 n行m列 nm矩阵,求最多包涵一个1的正方形的最大边长。
巨弱不会 O ( n 2 ) O(n^2) O(n2)做法,套了个二分答案 O ( n 2 log ⁡ n ) O(n^2\log n) O(n2logn) 过的,不过都需要优化输入。

int n, m;
bool a[N][N];
int sum[N][N];
bool ok(int mid) {
	if(mid == 1)
		return true;
	for(int i = mid; i <= n; i++) {
		for(int j = mid; j <= m; j++) {
			int i1 = i - mid;
			int j1 = j - mid;
			if(sum[i][j] + sum[i1][j1] - sum[i][j1]-sum[i1][j] <= 1) {
				return true;
			}
		}
	}
	return false;
}
inline int read()
{
	char ch = getchar();
	int ans0 = 0;
	while (!isdigit(ch))
	{
		ch = getchar();
	}
	while (isdigit(ch))
	{
		ans0 = ans0*10+ch-'0';
		ch = getchar();
	}
	return ans0;
}
void solve() {
	char c;
	n = read();
	m = read();
    bool flag = 0;
    for(int i = 1; i <= n; i++) {
    	for(int j =1 ; j <= m; j++) {
    		a[i][j] = read();
    		if(!a[i][j]) flag = 1;
    		sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + a[i][j];
    	}
    }
    if(!flag) {
    	printf("1\n");
    	return;
    }
    int l = 1, r = min(n, m);
    int ans = 1;
    while(l <= r) {
    	int mid = (l + r) >> 1;
    	if(ok(mid)) {
    		ans = mid;
    		l = mid + 1;
    	}
    	else {
    		r = mid - 1;
    	}
    }
    printf("%d\n", ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值