• 2014Noip提高组复赛Day2题解


    无线网络发射器选址

    题目描述 Description

    随着智能手机的日益普及,人们对无线网的需求日益增大。某城市决定对城市内的公共场所覆盖无线网。

    假设该城市的布局为由严格平行的 129 条东西向街道和 129 条南北向街道所形成的网格状,并且相邻的平行街道之间的距离都是恒定值 1 。东西向街道从北到南依次编号为0,1,2…128,南北向街道从西到东依次编号为 0,1,2…128。

    东西向街道和南北向街道相交形成路口,规定编号为 x 的南北向街道和编号为 y 的东西向街道形成的路口的坐标是(x, y)。在某些路口存在一定数量的公共场所。

    由于政府财政问题,只能安装一个大型无线网络发射器。该无线网络发射器的传播范围是一个以该点为中心,边长为 2*d 的正方形。传播范围包括正方形边界。

    例如下图是一个 d = 1 的无线网络发射器的覆盖范围示意图。

    现在政府有关部门准备安装一个传播参数为 d 的无线网络发射器,希望你帮助他们在城 市内找出合适的安装地点,使得覆盖的公共场所最多。

    输入描述 Input Description

    第一行包含一个整数 d,表示无线网络发射器的传播距离。

    第二行包含一个整数 n,表示有公共场所的路口数目。

    接下来 n 行,每行给出三个整数 x, y, k, 中间用一个空格隔开,分别代表路口的坐标(x, y)以及该路口公共场所的数量。同一坐标只会给出一次。

    输出描述 Output Description

    输出一行,包含两个整数,用一个空格隔开,分别表示能覆盖最多公共场所的安装地点方案数,以及能覆盖的最多公共场所的数量。

    样例输入 Sample Input

    1

    2

    4 4 10

    6 6 20

    样例输出 Sample Output

    1 30

    数据范围及提示 Data Size & Hint

    【数据范围】

    对于 100%的数据,1 ≤ d ≤ 20,1 ≤ n ≤ 20, 0 ≤ x ≤ 128, 0 ≤ y ≤ 128, 0 < k ≤ 1,000,000。

     思路: 枚举就行了,注意要从(0,0)开始

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int x[500],y[500],k[500],mp[500][500],pre[500][500],d,n,ans,cnt;
    inline int read()
    {
        int x=0;int f=1;
        char ch;
        ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-') f=-1;
            ch=getchar();
         } 
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    int main()
    {
        d=read();n=read();
        for(int i=1;i<=n;++i)
        {
            x[i]=read();y[i]=read();k[i]=read();
            mp[x[i]+50][y[i]+50]=k[i];
        } 
        pre[50][50]=mp[50][50];
        for(int i=50;i<=228+50;++i) pre[i][50]=pre[i-1][50]+mp[i][50];
        for(int j=50;j<=228+50;++j) pre[50][j]=pre[50][j-1]+mp[50][j];
        for(int i=51;i<=228+50;++i)
        {
            for(int j=51;j<=228+50;++j)
            {
                pre[i][j]=pre[i][j-1]+pre[i-1][j]-pre[i-1][j-1]+mp[i][j];
            }
        }
        for(int i=50;i<=128+50;++i)
        {
            for(int j=50;j<=128+50;++j)
            {
                int tot=0;
                tot=pre[i+d][j+d]-pre[i+d][j-d-1]-pre[i-d-1][j+d]+pre[i-d-1][j-d-1];
                if(tot==ans) ++cnt;
                else if(tot>ans) cnt=1,ans=tot;
            }
        }
        printf("%d %d
    ",cnt,ans);
        return 0;
        
    }

    寻找道路

    题目描述 Description

    在有向图G中,每条边的长度均为1,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:

    1.路径上的所有点的出边所指向的点都直接或间接与终点连通。

    2.在满足条件1的情况下使路径最短。

    注意:图G中可能存在重边和自环,题目保证终点没有出边。

    请你输出符合条件的路径的长度。

    输入描述 Input Description

    第一行有两个用一个空格隔开的整数n和m,表示图有n个点和m条边。

    接下来的m行每行2个整数x、y,之间用一个空格隔开,表示有一条边从点x指向点y。

    最后一行有两个用一个空格隔开的整数s、t,表示起点为s,终点为t。

    输出描述 Output Description

    输出文件名为road.out。

    输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。如果这样的路径不存在,输出-1。

    样例输入 Sample Input

    road.in

    road.out

    3 2

    1 2

    2 1

    1 3

    -1

    样例输出 Sample Output

    road.in

    road.out

    6 6

    1 2

    1 3

    2 6

    2 5

    4 5

    3 4

    1 5

    3

    数据范围及提示 Data Size & Hint

    对于30%的数据,0< n ≤10,0< m ≤20;

    对于60%的数据,0< n ≤100,0< m ≤2000;

    对于100%的数据,0< n ≤10,000,0< m ≤200,000,0< x,y,s,t≤n,x≠t。

     思路:要建反图,然后从终点开始跑bfs,判断每一条边是否能到达终点,若是不能则对边做标记,然后再从起点跑一遍dfs,边的起点被标记不能走的就不对其进行深搜,最后跑一遍spfa

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<queue>
      5 #define maxn 10010
      6 #define maxm 200010
      7 using namespace std;
      8 int head1[maxn],head2[maxn],ecnt1,ecnt2,dis[maxn],vis[maxn],s,t,n,m,can[maxn];
      9 const int inf=0x3f3f3f3f;
     10 inline int read()
     11 {
     12     int x=0;int f=1;
     13     char ch=getchar();
     14     while(ch<'0'||ch>'9')
     15     {
     16         if(ch=='-') f=-1;
     17         ch=getchar();
     18     } 
     19     while(ch>='0'&&ch<='9')
     20     {
     21         x=x*10+ch-'0';
     22         ch=getchar();
     23     }
     24     return x*f;
     25 }
     26 struct edge1
     27 {
     28     int u,v,w,can,next;
     29 }E1[maxm],E2[maxm];
     30 void add1(int u,int v)
     31 {
     32     E1[++ecnt1].u=u;
     33     E1[ecnt1].v=v;
     34     E1[ecnt1].w=1;
     35     E1[ecnt1].next=head1[u];
     36     head1[u]=ecnt1;
     37 }
     38 void add2(int u,int v)
     39 {
     40     E2[++ecnt2].u=u;
     41     E2[ecnt2].v=v;
     42     E2[ecnt2].w=1;
     43     E2[ecnt2].next=head2[u];
     44     head2[u]=ecnt2;
     45 }
     46 void bfs()
     47 {
     48     queue<int>q;
     49     vis[t]=1;
     50     q.push(t);
     51     while(!q.empty())
     52     {
     53         int u=q.front();
     54         q.pop();
     55         for(int i=head2[u];i;i=E2[i].next)
     56         {
     57             int v=E2[i].v;
     58             E1[i].can=1;
     59             if(!vis[v])
     60             {
     61                 vis[v]=1;
     62                 q.push(v);
     63             } 
     64         }
     65     }
     66 }
     67 void dfs(int x)
     68 {
     69     vis[x]=1;
     70     bool flg=1;
     71     for(int i=head1[x];i;i=E1[i].next)
     72     {
     73         int v=E1[i].v;
     74         flg&=E1[i].can;
     75         if(!vis[v]) dfs(v);
     76     }
     77     can[x]=flg;
     78 }
     79 void spfa()
     80 {
     81     queue<int>q;
     82     q.push(s);
     83     dis[s]=0;
     84     vis[s]=1;
     85     while(!q.empty())
     86     {
     87         int u=q.front();
     88         for(int i=head1[u];i;i=E1[i].next)
     89         {
     90             int v=E1[i].v;
     91             if(!can[v]) continue;
     92             if(dis[v]>dis[u]+E1[i].w)
     93             {
     94                 dis[v]=dis[u]+E1[i].w;
     95                 q.push(v);
     96                 vis[v]=1;
     97             }
     98         }
     99         q.pop();
    100         vis[u]=0;
    101      } 
    102 }
    103 int main()
    104 {
    105     n=read();m=read();
    106     for(int i=1;i<=m;++i)
    107     {
    108         int a,b;
    109         a=read();b=read();
    110         add1(a,b);
    111         add2(b,a);
    112     }
    113     s=read();
    114     t=read();
    115     bfs();
    116     memset(vis,0,sizeof(vis));
    117     dfs(s);
    118     if(!can[s])
    119     {
    120         puts("-1");
    121         return 0;
    122     }
    123     memset(vis,0,sizeof(vis));
    124     memset(dis,inf,sizeof(dis));
    125     spfa();
    126     printf("%d
    ",dis[t]);
    127     return 0;
    128  } 

     解方程

    题目描述 Description

    输入描述 Input Description

    输入文件名为equation.in。

    输入共n+2行。

    第一行包含2个整数n、m,每两个整数之间用一个空格隔开。

    接下来的n+1行每行包含一个整数,依次为a0,a1,a2,……,an。

    输出描述 Output Description

    输出文件名为equation.out。

    第一行输出方程在[1, m]内的整数解的个数。

    接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m]内的一个整数解。

    样例输入 Sample Input

    equation.in

    equation.out

    2 10

    1

    -2

    1

    1

    1

    equation.in

    equation.out

    2 10

    -3

    1

    2

    1

    2

    样例输出 Sample Output

    equation.in

    equation.out

    2 10

    1

    3

    2

    0

    数据范围及提示 Data Size & Hint

    思路:找一堆质数然后取模,枚举,质数越多就越能保证正确率(其实就是靠玄学。。)

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 typedef long long LL;
     6 typedef double db;
     7 inline int read()
     8 {
     9     int x=0,f=1;
    10     char ch=getchar();
    11     while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); }
    12     while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+ch-'0'; ch=getchar(); }
    13     return x*f;
    14 }
    15 const int MAXN=110;
    16 int n,m,pri[]={6529,7451,8363,9281,9829},a[5][MAXN],pre[5][MAXN],val[5][10010],ans1,ans2[1000010];
    17 void readBignum(int j)
    18 {
    19     int f=1;
    20     char ch=getchar();
    21     while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); }
    22     while(ch>='0'&&ch<='9')
    23     {
    24         for(int i=0;i<5;++i)
    25             a[i][j]=(a[i][j]*10+ch-'0')%pri[i];
    26         ch=getchar();
    27     }
    28     for(int i=0;i<5;++i)
    29         a[i][j]*=f;
    30     return;
    31 }
    32 int cal(int x)
    33 {
    34     int ret=0;
    35     for(int i=0;i<=n;++i)ret=(ret+a[x][i]*pre[x][i]%pri[x])%pri[x];
    36     if(ret<0)ret+=pri[x];
    37     return ret;
    38 }
    39 bool check(int x)
    40 {
    41     for(int i=0;i<5;++i)
    42         if(val[i][x%pri[i]])return false;
    43     return true;
    44 }
    45 int main()
    46 {
    47     n=read();m=read();
    48     for(int i=0;i<=n;++i)readBignum(i);
    49     for(int i=0;i<5;++i)
    50     {
    51         for(int j=1;j<pri[i];++j)
    52         {
    53             pre[i][0]=1;
    54             for(int k=1;k<=n;++k)pre[i][k]=(pre[i][k-1]*j)%pri[i];
    55             val[i][j]=cal(i);
    56         }
    57     }
    58     for(int i=1;i<=m;++i)if(check(i))ans2[++ans1]=i;
    59     printf("%lld
    ",ans1);
    60     for(int i=1;i<=ans1;++i)printf("%lld
    ",ans2[i]);
    61     return 0;
    62 }
  • 相关阅读:
    itextpdf 和 pdfbox 测试用例
    Java base64 编码、解码
    常用字体
    DIY 单片机 入门
    太难了。
    Java 之 native:JNI 本地方法测试实现
    Java 之 String 引用传递
    Java class 文件 方法的指令含义
    Spring学习文章链接
    数据结构_树_图_总结
  • 原文地址:https://www.cnblogs.com/mljkw-gsry/p/7721782.html
Copyright © 2020-2023  润新知