zoukankan      html  css  js  c++  java
  • 【NOIP 2016】初赛-完善程序 & 参考答案

    参考答案


     感觉这两题目都挺好的~~


    T1 交朋友

    简单描述:有n个人依次进入教室,每个人进入会找一个身高绝对值相差最小的人交朋友(相同时更想和高的交朋友),求每个人交的朋友.

    Solution:

    Sort,求出每个人的排名

    逆向思维,从后往前(每次删除,然后剩余的都是可以选的)

    链表存储前一个和后一个,每次删除发生改变

    发组福利数据

    in:

    6
    4 6 5 3 1 7

    out:

    2:1
    3:2
    4:1
    5:4
    6:2

    // <T1.cpp> - Sun Oct 23 22:05:36 2016
    // This file is made by YJinpeng,created by XuYike's black technology automatically.
    // Copyright (C) 2016 ChangJun High School, Inc.
    // I don't know what this program is.
    
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #define INF 0x7fffffff
    using namespace std;
    const int MAXN=100010;
    inline int gi() {
    	register int w=0,q=0;register char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')q=1,ch=getchar();
    	while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
    	return q?-w:w;
    }
    int as[MAXN],rank[MAXN],h[MAXN],pre[MAXN],nex[MAXN];
    bool cmp(int a,int b){return h[a]<h[b];}
    int main()
    {
    	freopen("T1.in","r",stdin);
    	freopen("T1.out","w",stdout);
    	int n=gi(),s;
        for(int i=1;i<=n;i++)h[i]=gi(),rank[i]=i;
        sort(rank+1,rank+1+n,cmp);
        for(int i=1;i<=n;i++)
            pre[rank[i]]=rank[i-1],nex[rank[i]]=rank[i+1];
        for(int i=n;i>=2;i--){
            s=INF;
            if(!pre[i])s=h[i]-h[pre[i]];
            if(!nex[i])s+=h[i]-h[nex[i]];
            if(s<0)as[i]=pre[i];
            else as[i]=nex[i];
            nex[pre[i]]=nex[i];
            pre[nex[i]]=pre[i];
        }
        for(int i=2;i<=n;i++)printf("%d:%d
    ",i,as[i]);
    	return 0;
    }
    

    T2 交通中断

    大意:给一个无向图,问第x个点中断时(与其他点连边全部删掉),从1号点到多少个点的最短路改变(包括不能到达,不包括x)

    Solution:

    先求出1到每个点的最短路,然后举删掉了哪个点,从1开始bfs(到达的是最短路,加入队列),这样贪心保证正确性,因为一个点可能可以从多个点跑相同长度的最短路到达.

    发组福利数据

    in:

    5 7
    1 2 1
    1 2 0
    1 3 4
    2 3 3
    4 5 1
    3 4 2
    1 4 3

    out:

    2:1
    3:0
    4:1
    5:0

    // <T2.cpp> - Sun Oct 23 22:05:36 2016
    // This file is made by YJinpeng,created by XuYike's black technology automatically.
    // Copyright (C) 2016 ChangJun High School, Inc.
    // I don't know what this program is.
    
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <queue>
    #define IN inline
    #define RG register
    #define INF 0x7fffffff
    using namespace std;
    inline int gi() {
    	register int w=0,q=0;register char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')q=1,ch=getchar();
    	while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
    	return q?-w:w;
    }
    struct SPFA{
        static const int N=6010,M=100010;
        queue<int>q;bool u[N];
        int n,m,t;int d[N],fr[N];int to[M],ne[M],W[M];
        IN void link(RG int u,RG int v,RG int w){
            to[++t]=v;ne[t]=fr[u];fr[u]=t;W[t]=w;
        }
        void read(){
            n=gi(),m=gi();
            while(m--){
                int u=gi(),v=gi(),w=gi();
                link(u,v,w);link(v,u,w);
            }
        }
        void Spfa(int begin){
            for(int i=1;i<=n;i++)d[i]=INF;
            q.push(begin);d[begin]=0;memset(u,0,sizeof(u));
            while(!q.empty()){
                int x=q.front();q.pop();u[x]=0;
                for(int o=fr[x],y;y=to[o],o;o=ne[o])
                    if(d[x]+W[o]<d[y]){
                        d[y]=d[x]+W[o];
                        if(!u[y])u[y]=1,q.push(y);
                    }
            }
        }
        void Work(){
            read();Spfa(1);
            while(!q.empty())q.pop();
            for(int i=2;i<=n;i++){
                memset(u,0,sizeof(u));
                q.push(1);u[1]=1;
                while(!q.empty()){
                    int x=q.front();q.pop();
                    for(int o=fr[x],y;y=to[o],o;o=ne[o])
                        if(y!=i&&d[x]+W[o]==d[y]&&!u[y])
                            u[y]=1,q.push(y);
                }int ans=0;
                for(int j=1;j<=n;j++)ans+=1-u[j];
                printf("%d:%d
    ",i,ans-1);
            }
        }
    }e;
    int main()
    {
    	freopen("T2.in","r",stdin);
    	freopen("T2.out","w",stdout);
    	e.Work();
    	return 0;
    }
    

      

  • 相关阅读:
    JAVA之数组
    Linux之判断字符串是否为空
    Python之操作HBASE数据库
    【转】Linux之crontab定时任务命令
    Python之shutil模块(复制移动文件)
    JAVA之列表集合ArrayList
    Python之多线程多进程
    前端之Javascript
    前端之DOM操作
    【转】写一个简单的爬虫来批量爬取新浪网的新闻
  • 原文地址:https://www.cnblogs.com/YJinpeng/p/5988443.html
Copyright © 2011-2022 走看看