zoukankan      html  css  js  c++  java
  • 11.6 校内模拟赛解题报告

    T1

    考虑没个点应该向左或者向右传多少,或者它自身接受左边传来了多少,右边传来了多少,因为一次只能传一个,所以传送的多少就是时间。
    对所有的这些情况取 max。

    /*
    Date:
    Source:
    Knowledge: 
    */
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #define orz cout << "AK IOI" << "\n"
    #define int long long
    
    using namespace std;
    const int maxn = 1e5 + 10;
    
    int read()
    {
    	int x = 0, f = 1; char ch = getchar();
    	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
    	while(ch <= '9' && ch >= '0') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
    	return x * f;
    }
    void print(int X)
    {
    	if(X < 0) X = ~(X - 1), putchar('-');
    	if(X > 9) print(X / 10);
    	putchar(X % 10 ^ '0');
    }
    int Max(int a, int b){
    	return a > b ? a : b;
    }
    int Min(int a, int b){
    	return a < b ? a : b;
    }
    int n, ans, a[maxn], sum[maxn];
    signed main()
    {
    	//freopen("link.in", "r", stdin);
    	//freopen("link.out", "w", stdout);
    	n = read();
    	for(int i = 1; i <= n; i++) a[i] = read(), sum[i] = sum[i - 1] + a[i];
    	int tmp = sum[n] / n;
        for(int i = 1; i <= n; i++)
        {
            int tmp1 = sum[i - 1] - (tmp * (i - 1)); //左边的
    		int tmp2 = sum[n] - sum[i] - tmp * (n - i); // 右边的
    		if(tmp1 < 0 && tmp2 < 0) ans = Max(ans, abs(tmp1 + tmp2));
    		else ans = Max(ans, Max(abs(tmp1), abs(tmp2))); 
        }
        print(ans);
    	//fclose(stdin);
    	//fclose(stdout);
    	return 0;
    }
    

    T2

    答案与城市的顺序无关,题目要求取走的数必须是所有已经取走的数的倍数或者约数。对数组进行排序,转化成取倍数的问题,用类似于埃氏筛的方法求解。

    /*
    Date:
    Source:
    Knowledge:
    */
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #define orz cout << "AK IOI" << "\n"
    
    using namespace std;
    const int maxn = 1e6 + 10;
    
    int read()
    {
    	int x = 0, f = 1; char ch = getchar();
    	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
    	while(ch <= '9' && ch >= '0') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
    	return x * f;
    }
    void print(int X)
    {
    	if(X < 0) X = ~(X - 1), putchar('-');
    	if(X > 9) print(X / 10);
    	putchar(X % 10 ^ '0');
    }
    int Max(int a, int b){
    	return a > b ? a : b;
    }
    int Min(int a, int b){
    	return a < b ? a : b;
    }
    int n, ans, a[maxn], f[maxn], cnt[maxn]; 
    
    int main()
    {
    	//freopen("pigeon.in", "r", stdin);
    	//freopen("pigeon.out", "w", stdout);
    	n = read();
    	for(int i = 1; i <= n; i++) a[i] = read(), f[a[i]]++, cnt[a[i]]++;
    	sort(a + 1, a + n + 1);
    	for(int i = 1; i <= maxn; i++)
    	{
    		if(f[i])
    		{
    			ans = Max(ans, f[i]);
    			for(int j = i + i; j <= maxn; j += i)
    				if(cnt[j]) f[j] = Max(f[j], f[i] + cnt[j]);
    		}
    	}
    	print(ans);
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    T3

    二分答案。
    每次检验的时候会发现,一组卡牌中的一张选了会导致其他某组卡牌必须选另外一张,从而转化为 2-SAT 问题。
    对于 所有卡牌战斗力的最大值减去最小值小于等于 100 的部分分,输出 \(0\)
    由于数据范围过大,无法直接 2-SAT 建图,注意到所有的边都是在一个区间里面的边,所以用线段树优化建图。

    贴一下 std 吧。

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    
    using namespace std;
    
    const int BUF_SIZE = 30;
    char buf[BUF_SIZE], *buf_s = buf, *buf_t = buf + 1;
      
    #define PTR_NEXT() \
        { \
            buf_s ++; \
            if (buf_s == buf_t) \
            { \
                buf_s = buf; \
                buf_t = buf + fread(buf, 1, BUF_SIZE, stdin); \
            } \
        }
       
    #define readint(_n_) \
        { \
            while (*buf_s != '-' && !isdigit(*buf_s)) \
                PTR_NEXT(); \
            bool register _nega_ = false; \
            if (*buf_s == '-') \
            { \
                _nega_ = true; \
                PTR_NEXT(); \
            } \
            int register _x_ = 0; \
            while (isdigit(*buf_s)) \
            { \
                _x_ = _x_ * 10 + *buf_s - '0'; \
                PTR_NEXT(); \
            } \
            if (_nega_) \
                _x_ = -_x_; \
            (_n_) = (_x_); \
        }
    
    #define readstr(_s_) \
        { \
            while (!isupper(*buf_s)) \
                PTR_NEXT(); \
            char register *_ptr_ = (_s_); \
            while (isupper(*buf_s) || *buf_s == '-') \
            { \
                *(_ptr_ ++) = *buf_s; \
                PTR_NEXT(); \
            } \
            (*_ptr_) = '\0'; \
        }
    
    #define readlonglong(_n_) \
        { \
            while (*buf_s != '-' && !isdigit(*buf_s)) \
                PTR_NEXT(); \
            bool register _nega_ = false; \
            if (*buf_s == '-') \
            { \
                _nega_ = true; \
                PTR_NEXT(); \
            } \
            long long register _x_ = 0; \
            while (isdigit(*buf_s)) \
            { \
                _x_ = _x_ * 10 + *buf_s - '0'; \
                PTR_NEXT(); \
            } \
            if (_nega_) \
                _x_ = -_x_; \
            (_n_) = (_x_); \
        }
    
    #define wmt 1,(n<<1),1
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    
    const int maxn=200010;
    const int maxp=maxn+(maxn<<2);
    const int maxm=maxn+maxp+maxn*40;
    
    int n,size,cnt,en,t,dfn[maxp],low[maxp],s[maxp],belong[maxp],pos[maxn];
    
    bool instack[maxp];
    
    struct edge
    {
    	int e;
    	edge *next;
    }*v[maxp],ed[maxm];
    
    void add_edge(int s,int e)
    {
    	en++;
    	ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;
    }
    
    struct rec
    {
    	int v,p;
    	rec(){}
    	rec(int a,int b)
    	{
    		v=a;p=b;
    	}
    }z[maxn];
    
    bool operator<(const rec &a,const rec &b)
    {
    	return a.v<b.v;
    }
    
    void dfs(int p)
    {
    	t++;
    	dfn[p]=low[p]=t;
    	instack[p]=true;
    	s[++size]=p;
    	for (edge *e=v[p];e;e=e->next)
    		if (!dfn[e->e])
    		{
    			dfs(e->e);
    			low[p]=min(low[p],low[e->e]);
    		}
    		else
    		{
    			if (instack[e->e]) low[p]=min(low[p],dfn[e->e]);
    		}
    	if (dfn[p]==low[p])
    	{
    		cnt++;
    		while (s[size]!=p)
    		{
    			belong[s[size]]=cnt;
    			instack[s[size]]=false;
    			size--;
    		}
    		belong[p]=cnt;
    		instack[p]=false;
    		size--;
    	}
    }
    
    void build(int l,int r,int rt)
    {
    	if (l==r)
    	{
    		add_edge(rt+(n<<1),z[l].p<=n?z[l].p+n:z[l].p-n);
    		return;
    	}
    	int m=(l+r)>>1;
    	build(lson);
    	build(rson);
    	add_edge(rt+(n<<1),(rt<<1)+(n<<1));
    	add_edge(rt+(n<<1),(rt<<1|1)+(n<<1));
    }
    
    void insert(int l,int r,int rt,int nowl,int nowr,int p)
    {
    	if (nowl<=l && r<=nowr)
    	{
    		add_edge(p,rt+(n<<1));
    		return;
    	}
    	int m=(l+r)>>1;
    	if (nowl<=m) insert(lson,nowl,nowr,p);
    	if (m<nowr) insert(rson,nowl,nowr,p);
    }
    
    bool check(int k)
    {
    	en=0;cnt=0;
    	memset(v,0,sizeof(v));
    	memset(dfn,0,sizeof(dfn));
    
    	build(wmt);
    
    	int r=1,l=1;
    
    	for (int a=1;a<=(n<<1);a++)
    	{
    		int op,p=z[a].p;
    		if (p<=n) op=pos[p+n];
    		else op=pos[p-n];
    		while (r<=a && z[r].v <= z[a].v-k)
    			r++;
    		if (r<a && r>=1 && z[r].v > z[a].v-k) 
    		{
    			if (op>=r && op<=a-1)
    			{
    				if (op>r) insert(wmt,r,op-1,z[a].p);
    				if (op<a-1) insert(wmt,op+1,a-1,z[a].p);
    			}
    			else insert(wmt,r,a-1,z[a].p);
    		}
    		while (l<=(n<<1) && z[l].v < z[a].v+k)
    			l++;
    		l--;
    		if (l>a && l<=(n<<1) && z[l].v < z[a].v+k) 
    		{
    			if (op>=a+1 && op<=l)
    			{
    				if (op>a+1) insert(wmt,a+1,op-1,z[a].p);
    				if (op<l) insert(wmt,op+1,l,z[a].p);
    			}
    			else insert(wmt,a+1,l,z[a].p);
    		}
    	}
    
    	for (int a=1;a<=(n<<1);a++)
    		if (!dfn[a]) dfs(a);
    	for (int a=1;a<=n;a++)
    		if (belong[a]==belong[a+n]) return false;
    	return true;
    }
    
    int main()
    {
    	readint(n);
    	int minv=0x3f3f3f3f,maxv=-0x3f3f3f3f;
    	int x=0;
    	for (int a=1;a<=n;a++)
    	{
    		int v1,v2;
    		readint(v1);
    		readint(v2);
    		z[++x]=rec(v1,a);
    		z[++x]=rec(v2,a+n);
    		minv=min(minv,min(v1,v2));
    		maxv=max(maxv,max(v1,v2));
    	}
    	if (maxv-minv+1 < n)
    	{
    		printf("0\n");
    		return 0;
    	}
    	sort(z+1,z+x+1);
    	for (int a=1;a<=(n<<1);a++)
    		pos[z[a].p]=a;
    	int l=0,r=1000000001;
    	while (l+1!=r)
    	{
    		int m=(l+r)>>1;
    		if (check(m)) l=m;
    		else r=m;
    	}
    	printf("%d\n",l);
    
    	return 0;
    }
    
  • 相关阅读:
    第九次作业
    第八次作业
    第七次作业
    组合数学—递推关系与母函数
    组合数学—排列组合
    三角函数
    OpenCV初步
    计算机视觉如何入门
    GDB调试技巧:总结篇
    PyQt5之窗口类型
  • 原文地址:https://www.cnblogs.com/yangchengcheng/p/15519787.html
Copyright © 2011-2022 走看看