zoukankan      html  css  js  c++  java
  • 2019 ICPC 南昌网络赛

    2019 ICPC 南昌网络赛

    比赛时间:2019.9.8
    比赛链接:The 2019 Asia Nanchang First Round Online Programming Contest

    总结 // 史上排名最高一次,开场不到两小时队友各A一题加水题共四题,排名瞬间升至三四十名 // 然后后三小时就自闭了,一题都没有突破。。。最后排名211 hhhh
     

    B. Fire-Fighting Hero

    题意

    队友做的,待补。
     

    AC代码

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int N = 2010;
    int head[N],cnt;
    struct node
    {
    	int v,nxt,w;
    }e[N*N];
    void addedge(int u,int v,int w)
    {
    	e[cnt].v= v;
    	e[cnt].nxt = head[u];
    	e[cnt].w = w;
    	head[u] = cnt++;
    }
    int dis[N];
    int mp[N][N];
    queue<int>q;
    int vis[N];
    void spfa()
    {
    	while(!q.empty())
    	{
    		int u = q.front();
    		//cout<<u<<endl;
    		q.pop();
    		vis[u] = 0;
    		for(int i=head[u];~i;i=e[i].nxt)
    		{
    			int v = e[i].v;
    			//cout<<" "<<v<<endl;
    			if(dis[v]>dis[u]+mp[u][v])
    			{
    				dis[v] = dis[u]+mp[u][v];
    				if(vis[v]==0)
    				{
    					q.push(v);
    					vis[v] = 1;
    				}
    			}
    		}
    	}
    }
    int main()
    {
    	int T;scanf("%d",&T);
    	while(T--)
    	{
    		memset(head,-1,sizeof(head));
    		cnt = 0;
    		int V,E,S,K,C;
    		scanf("%d%d%d%d%d",&V,&E,&S,&K,&C);
    		for(int i=1;i<=V;++i)
    		{
    			vis[i]=0;
    			dis[i]=(1<<30);
    			for(int j=1;j<=V;++j)
    				mp[i][j]=(1<<30);
    		}	
    		for(int i=1;i<=K;++i)
    		{
    			int d;scanf("%d",&d);
    			dis[d] = 0;
    			q.push(d);
    			vis[d] = 1;
    		}
    		for(int i=1;i<=E;++i)
    		{
    			int u,v,w;scanf("%d%d%d",&u,&v,&w);
    			if(mp[u][v]==(1<<30))
    			{
    				addedge(u,v,w);
    				addedge(v,u,w);
    			}
    			mp[u][v]=mp[v][u]=min(mp[u][v],w);
    		}
    		spfa();
    		int ptr = 0;
    		for(int i=1;i<=V;++i)
    			if(dis[i]!=(1<<30))
    				ptr = max(ptr,dis[i]);
    		for(int i=1;i<=V;++i)
    		{
    			vis[i] = 0;
    			dis[i]=(1<<30);
    		}
    		dis[S] = 0;
    		while(!q.empty())q.pop();
    		q.push(S);
    		vis[S] = 1;
    		spfa();
    		int hero = 0;
    		for(int i=1;i<=V;++i)
    			if(dis[i]!=(1<<30))
    				hero = max(hero,dis[i]);
    		if(hero<=ptr*C)
    			printf("%d
    ",hero);
    		else
    			printf("%d
    ",ptr);
    	}
    	return 0;
    }
    

    E. Magic Master

    题意

    桌子上有一叠 N 张扑克牌,每张牌有一个编号(1~N),按照如下两个过程取出:

    1. 取走这堆扑克牌最上面的一张牌,放到手上。手上有牌的话放到所有牌最下面。
    2. 如果桌子上还有剩余牌,就把桌上的最上面的牌插入到底部,操作 M 次。
      若最后手上牌的编号为降序,求开始桌上每张牌的编号是多少。有 Q 次询问,每次给出桌上从上到下第 k 张牌的编号。
       

    思路

    开始粗略一算,好像能够直接模拟算出初始编号。写完发现复杂度到达 (O(T*N*M)),肯定T了。
    捂着代码没交,发现 Q 最大只有100,那么只处理前100次查询的结果,调了半天样例没跑出来。
    printf调试发现有先算好的结果,于是加上了类似记忆化的标记。然后交了就A了。
    赛后有大佬没过问我这个约瑟夫环怎么处理的,我才意识到这是约瑟夫环啊,他们为什么会T呢
    可能我用的 STL 的queue很优秀吧 o( ̄▽ ̄)o
     

    AC代码

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int maxn = 40000010;
    
    int n, m;
    int ans[maxn], now;
    
    queue<int> q;
    void solve(int k) {
        if(ans[k]!=-1) {
            printf("%d
    ", ans[k]);
            return;
        }
        while(q.size()) {
            int num = q.front();  q.pop();
            ans[num] = ++now;
    
            bool flag = 0;
            if(num==k) {
                printf("%d
    ", ans[k]);
                flag = true;
            }
            
            if(q.empty()) break;
            for(int i=1;i<=m;i++) {
                int num = q.front();  q.pop();
                q.push(num);
            }
    
            if(flag) break;
        }
    }
    
    int main() {
        int T; cin>>T;
        while(T--) {
            int Q;
            scanf("%d %d %d", &n, &m, &Q);
            
            memset(ans, -1, sizeof(ans));
            while(q.size()) q.pop();
            for(int i=1;i<=n;i++) q.push(i);
            now = 0;
            while(Q--) {
                int k;
                scanf("%d", &k);
                solve(k);
            }
        }
        
        return 0;
    }
    

    把第一遍写的暴力模拟测了一下,居然也过了。。。这题好SB...

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int maxn = 40000010;
    
    int n, m;
    int ans[maxn], now;
    
    queue<int> q;
    void solve() {
        while(q.size()) q.pop();
        now = 0;
        
        for(int i=1;i<=n;i++) q.push(i);
        while(q.size()) {
            ans[q.front()] = ++now;
            q.pop();
            
            if(q.empty()) break;
            for(int i=1;i<=m;i++) {
                int num = q.front(); q.pop();
                q.push(num);
            }
        }
    }
    
    int main() {
        int T; cin>>T;
        while(T--) {
            int q;
            scanf("%d %d %d", &n, &m, &q);
            solve();
            while(q--) {
                int k;
                scanf("%d", &k);
                printf("%d
    ", ans[k]);
            }
        }
        return 0;
    }
    

    G. Pangu Separates Heaven and Earth

    题意

    签到题。
     

    AC代码

    略。
     

    H. The Nth Item

    题意

    定义

    [F(0)=0, F(1)=1\ F(n)=3∗F(n−1)+2∗F(n−2), (n≥2) ]

    (Q) 次询问,求 (F(N)) 。((1 leq Q leq 10^7, 0 leq N leq 10^{18}))
     

    思路

    队友开始觉得BM线性递推可以做,我高高兴兴抄起板子改改一交就TLE。
    然后我一看就两项完全不用线性递推啊,直接矩阵快速幂就好了。
    我在一边写矩阵快速幂,并提示把中间计算结果存下来,让队友想办法优化。
    然后队友构造了一组数据我T了但线性递推算出来了,于是就交了AC了。
     

    AC代码

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <map>
    using namespace std;
    
    #define rep(i,a,n) for(int i=a;i<n;i++)
    #define per(i,a,n) for(int i=n-1;i>=a;i--)
    #define pb push_back
    #define all(x) (x).begin(), (x).end()
    #define SZ(x) ((int)(x).size())
    
    typedef long long ll;
    typedef vector<ll> VLL;
    const ll mod = 998244353;
    
    ll powmod(ll a, ll b) {
    	ll res=1;a%=mod;
    	for(;b;b>>=1) {
    		if(b&1) res=res*a%mod;
    		a=a*a%mod;
    	}
    	return res;
    }
    
    namespace linear_seq {
        const int N = 100010;
        ll res[N], base[N], _c[N], _md[N];
    
        VLL Md;
        void mul(ll a[], ll b[], int k) {
            for(int i=0;i<k+k;i++)
            	_c[i] = 0;
            for(int i=0;i<k;i++)
            	if(a[i])
            		for(int j=0;j<k;j++)
            			_c[i+j] = (_c[i+j] + a[i]*b[j]%mod) % mod;
    
            for(int i=k+k-1;i>=k;i--) 
            	if(_c[i])
                	rep(j,0,SZ(Md))
                		_c[i-k+Md[j]] = (_c[i-k+Md[j]] - _c[i] * _md[Md[j]]%mod) % mod;
    
            for(int i=0;i<k;i++)
            	a[i] = _c[i];
        }
    
        ll solve(ll n, VLL a, VLL b) {
            ll ans = 0, pnt = 0;
            int k = SZ(a);
            for(int i=0;i<k;i++)
            	_md[k-1-i]=-a[i];
            _md[k]=1;
    
            Md.clear();
            for(int i=0;i<k;i++)
            	if(_md[i]!=0) Md.push_back(i);
            for(int i=0;i<k;i++)
            	res[i]=base[i]=0;
            res[0]=1;
    
            while((1ll<<pnt)<=n) pnt++;
            for(int p=pnt;p>=0;p--) {
                mul(res, res, k);
                if((n>>p)&1) {
                    for(int i=k-1;i>=0;i--)
                    	res[i+1]=res[i];res[0]=0;
                    rep(j,0,SZ(Md))
                		res[Md[j]]=(res[Md[j]] - res[k]*_md[Md[j]]%mod) % mod;
                }
            }
    
            for(int i=0;i<k;i++)
            	ans = (ans + res[i]*b[i]%mod) % mod;
            if(ans<0) ans += mod;
            return ans;
        }
    
        VLL BM(VLL s) {
            VLL C(1,1), B(1,1);
            int L=0,m=1,b=1;
            rep(n,0,SZ(s)) {
                ll d=0;
                rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i]%mod) % mod;
                if(d==0) ++m;
                else if(2*L<=n) {
                    VLL T=C;
                    ll c=mod-d*powmod(b,mod-2)%mod;
                    while(SZ(C)<SZ(B)+m) C.pb(0);
                    rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i]%mod) % mod;
                    L=n+1-L; B=T; b=d; m=1;
                } else {
                    ll c = mod- d*powmod(b, mod-2)%mod;
                    while(SZ(C)<SZ(B)+m) C.pb(0);
                    rep(i,0,SZ(B))
                    	C[i+m]=(C[i+m]+c*B[i]%mod) % mod;
                    ++m;
                }
            }
            return C;
        }
    };
    
    VLL a, c;
    ll fib[110];
    
    void init() {
        fib[1] = 1;
        for(int i=2;i<110;i++) {
            fib[i] = (3*fib[i-1] + 2*fib[i-2]) % mod;
        } 
    
        for(int i=1;i<=100;i++) {
            a.pb(fib[i]);
        }
    
        c = linear_seq::BM(a);
        c.erase(c.begin());
        rep(i,0,SZ(c))
        c[i] = (mod-c[i])%mod;
    }
    
    map<ll,ll>mp;
    int main() {
        init();
    
        int T; ll N;
        scanf("%d %lld", &T, &N);
        ll RES = 0;
        ll ans = 0;
        while(T--) {
            N = (ans*ans)^N;
            if(mp[N]) ans = mp[N];
            else ans = linear_seq::solve(N-1, c, VLL(a.begin(), a.begin()+SZ(c)));
            mp[N]=ans;
            RES ^= ans;
            // printf("%lld
    ", ans);
        }
        printf("%lld
    ", RES);
        return 0;
    }
    
    /*
    卡矩阵快速幂的数据
    10000000 473844410
    */
    

     
    (未完待补。。)

  • 相关阅读:
    month(字段)、year(字段)
    简单音乐播放器实现
    Mp3音乐文件列表实现
    读取SD卡中所有MP3文件
    java基础复习 之 多态
    JavaWeb学习过程 之c3p0的使用
    JavaWeb学习过程 之MVC模式下的查询
    行转列:总结
    如何快速禁用约束 (解决ORA-O2266问题)
    PLSQL Developer 11 使用技巧(持续更新)
  • 原文地址:https://www.cnblogs.com/izcat/p/11495097.html
Copyright © 2011-2022 走看看