zoukankan      html  css  js  c++  java
  • NOIP模拟 7.04

    魔术球问题弱化版(ball.c/.cpp/.pas)

    题目描述

    假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2,3,…的球。

    1)每次只能在某根柱子的最上面放球。

    2)在同一根柱子中,任何 2 个相邻球的编号之和为完全平方数。

    试设计一个算法,计算出在 n 根柱子上最多能放多少个球。例如,在 4 根柱子上最多可放 11 个球。

    对于给定的 n,计算在 n 根柱子上最多能放多少个球。

    输入描述

    1 行有 1 个正整数 n,表示柱子数。

    输出描述

    一行表示可以放的最大球数

    4

    样例输出。

    样例输入

    11

    题目限制(为什么说弱化版就在这里)

    N<=60,时限为3s

     

    【题解】

    暴力。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 #include <queue>
     7 #include <cmath> 
     8 
     9 const int INF = 0x3f3f3f3f;
    10 const int MAXN = 60 + 10;
    11 
    12 inline void read(long long &x)
    13 {
    14     x = 0;char ch = getchar();char c = ch;
    15     while(ch > '9' || ch < '0')c = ch, ch = getchar();
    16     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
    17     if(c == '-')x = -x;
    18 }
    19 
    20 long long ans,num[MAXN],n;
    21 
    22 void dfs(int step)
    23 {
    24     for(int i = 1;i <= n;++ i)
    25     {
    26         if(!num[i])
    27         {
    28             num[i] = step;
    29             ans = step;
    30             dfs(step + 1);
    31             return;
    32         }
    33         int k = sqrt(num[i] + step);
    34         if(k * k == num[i] + step)
    35         {
    36             ans = step;
    37             num[i] = step;
    38             dfs(step + 1);
    39             break;
    40         }
    41     }
    42     return;
    43 }
    44 
    45 int main()
    46 {
    47     read(n);
    48     dfs(1);
    49     printf("%lld", ans);
    50     return 0;
    51 } 
    View Code

    2.征兵(conscription.c/.cpp/.pas)
    一个国王,他拥有一个国家。最近他因为国库里钱太多了,闲着蛋疼要征集一只部队要保卫国家。他选定了N个女兵和M个男兵,但事实上每征集一个兵他就要花10000RMB,即使国库里钱再多也伤不起啊。他发现,某男兵和某女兵之间有某种关系(往正常方面想,一共R种关系),这种关系可以使KING少花一些钱就可以征集到兵,不过国王也知道,在征兵的时候,每一个兵只能使用一种关系来少花钱。这时国王向你求助,问他最少要花多少的钱。

    读入(conscription.in)
    第一行:T,一共T组数据。
    接下来T组数据,
    第一行包括N,M,R
    接下来的R行 包括Xi,Yi,Vi 表示如果招了第Xi个女兵,再招第Yi个男兵能省Vi元(同样表示如果招了第Yi个男兵,再招第Xi个女兵能也省Vi元)
    输出(conscription.out)
    共T行,表示每组数据的最终花费是多少(因为国库里的钱只有2^31-1,所以保证最终花费在maxlongint范围内)
    样例输入
    2

    5 5 8
    4 3 6831
    1 3 4583
    0 0 6592
    0 1 3063
    3 3 4975
    1 3 2049
    4 2 2104
    2 2 781

    5 5 10
    2 4 9820
    3 2 6236
    3 1 8864
    2 4 8326
    2 0 5156
    2 0 1463
    4 1 2439
    0 4 4373
    3 4 8889
    2 4 3133
    样例输出
    71071
    54223
    数据范围
    数据保证
    T<=5 ,m,n<=10000,r<=50000,Xi<=m,Yi<=n,Vi<=10000,结果<=2^31-1

    【题解】

    最大生成树。开始读错题了,以为是KM。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 #include <queue>
     7 
     8 const int INF = 0x3f3f3f3f;
     9 const int MAXN = 1000000 + 10;
    10 const int MAXM = 1000000 + 10;
    11 
    12 inline void read(int &x)
    13 {
    14     x = 0;char ch = getchar();char c = ch;
    15     while(ch > '9' || ch < '0')c = ch, ch = getchar();
    16     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
    17     if(c == '-')x = -x;
    18 }
    19 
    20 int u[MAXM],v[MAXM],w[MAXM],cnt[MAXM];
    21 int t,n,m,r;
    22 int fa[MAXN];
    23 long long ans;
    24 
    25 bool cmp(int a, int b)
    26 {
    27     return w[a] >= w[b];
    28 }
    29 
    30 int find(int x)
    31 {
    32     return x == fa[x] ? x : fa[x] = find(fa[x]);
    33 }
    34 
    35 int main()
    36 {
    37     read(t);
    38     for(;t;--t)
    39     {
    40         ans = 0;
    41         read(n);read(m);read(r);
    42         int tmp = (n + m) << 1;
    43         for(register int i = 0;i <= tmp;++ i)
    44             fa[i] = i;
    45         for(register int i = 0;i <= r;++ i)
    46             cnt[i] = i;
    47         for(register int i = 1; i <= r;++ i)
    48         {
    49             read(u[i]);read(v[i]);read(w[i]);
    50             u[i] = u[i] << 1;
    51             v[i] = v[i] << 1 | 1;
    52         } 
    53         std::sort(cnt + 1, cnt + 1 + r, cmp);
    54         for(register int i = 1;i <= r;++ i)
    55         {
    56             int x = find(u[cnt[i]]);
    57             int y = find(v[cnt[i]]);
    58             if(x != y)
    59             {
    60                 ans += w[cnt[i]];
    61                 fa[x] = y;
    62             }
    63         }
    64         printf("%lld
    ", (long long)(n + m) * 10000 - ans) ;
    65     }
    66     return 0;
    67 } 
    View Code

    3.坑爹的GPS(gpsduel.c/.cpp/.pas)

    有一天,FJ买了一辆车,但是,他一手下载了两个GPS系统。好了现在麻烦的事情来了,GPS有一个功能大概大家也知道,如果FJ没有按照GPS内置地图的最短路走,GPS就会报错来骚扰你。现在FJ准备从他的农舍(在1这个点)开车到他的谷屋(n这个点)。FJ给了你两个GPS系统内置地图的信息,他想知道,他最少会听到多少次报错(如果FJ走的路同时不满足两个GPS,报错次数+2)

    读入:第一行:n,k;n表示有FJ的谷屋在哪,同时保证GPS内置地图里的点没有超过n的点。K表示GPS内置地图里的路有多少条,如果两个点没有连接则表明这不是一条通路。

       接下来k行,每行4个数X,Y,A,B分别表示从X到Y在第一个GPS地图里的距离是A,在第二个GPS地图里的是B。注意由于地形的其他因素GPS给出的边是有向边。

    输出:一个值,表示FJ最少听到的报错次数。

    样例输入:

    5 7

    3 4 7 1

    1 3 2 20

    1 4 17 18

    4 5 25 3

    1 2 10 1

    3 5 4 14

    2 4 6 5

    样例输出:

    1

    解释

    FJ选择的路线是1 2 4 5,但是GPS 1认为的最短路是1到3,所以报错一次,对于剩下的2 4 5,两个GPS都不会报错。

    数据范围

    N<=10000,至于路有多少条自己算吧。数据保证所有的距离都在2^31-1以内。

    来源

    USACO 2014年 全美公开赛银组第二题(各位轻虐银组题)

    【题解】

    三次最短路。

    先建反图,求出每个点到终点的最短路。然后求走每条边会引起的错误值的变化,再求最短路即可。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #include <queue>
      7 
      8 const int INF = 0x3f3f3f3f;
      9 const int MAXN = 200000 + 10;
     10 const int MAXQ = 300000 + 10;
     11 const int MAXM = 1000000 + 10;
     12 
     13 inline void read(int &x)
     14 {
     15     x = 0;char ch = getchar();char c = ch;
     16     while(ch > '9' || ch < '0')c = ch, ch = getchar();
     17     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
     18     if(c == '-')x = -x;
     19 }
     20 
     21 struct Edge
     22 {
     23     int u,v,next,w;
     24 }edge1[MAXM],edge2[MAXM],edge3[MAXM];
     25 int head1[MAXN],head2[MAXN],head3[MAXN],cnt1,cnt2,cnt3;
     26 int b1[MAXN],b2[MAXN],b3[MAXN];
     27 long long d1[MAXN],d2[MAXN],d3[MAXN];
     28 int n,m;
     29 
     30 void insert1(int a, int b, int c){edge1[++cnt1] = Edge{a, b, head1[a], c};head1[a] = cnt1;}
     31 void insert2(int a, int b, int c){edge2[++cnt2] = Edge{a, b, head2[a], c};head2[a] = cnt2;}
     32 void insert3(int a, int b, int c){edge3[++cnt3] = Edge{a, b, head3[a], c};head3[a] = cnt3;}
     33 
     34 std::queue<int> q;
     35 
     36 void SPFA1()
     37 {
     38     memset(d1, 0x3f, sizeof(d1));
     39     q.push(n);
     40     b1[n] = 1;
     41     d1[n] = 0;
     42     register int pos;
     43     while(!q.empty())
     44     {
     45         int u = q.front();
     46         q.pop();
     47         b1[u] = 0;
     48         for(pos = head1[u];pos;pos = edge1[pos].next)
     49         {
     50             int v = edge1[pos].v;
     51             if(d1[v] > d1[u] + edge1[pos].w)
     52             {
     53                 d1[v] = d1[u] + edge1[pos].w;
     54                 if(!b1[v])
     55                 {
     56                     q.push(v);
     57                     b1[v] = 1;
     58                 }
     59             }
     60         }
     61     }
     62 }
     63 
     64 void SPFA2()
     65 {
     66     memset(d2, 0x3f, sizeof(d2));
     67     q.push(n);
     68     b2[n] = 1;
     69     d2[n] = 0;
     70     register int pos;
     71     while(!q.empty())
     72     {
     73         int u = q.front();
     74         q.pop();
     75         b2[u] = 0;
     76         for(pos = head2[u];pos;pos = edge2[pos].next)
     77         {
     78             int v = edge2[pos].v;
     79             if(d2[v] > d2[u] + edge2[pos].w)
     80             {
     81                 d2[v] = d2[u] + edge2[pos].w;
     82                 if(!b2[v])
     83                 {
     84                     q.push(v);
     85                     b2[v] = 1;
     86                 }
     87             }
     88         }
     89     }
     90 }
     91 
     92 void SPFA3()
     93 {
     94     memset(d3, 0x3f, sizeof(d3));
     95     q.push(1);
     96     b3[1] = 1;
     97     d3[1] = 0;
     98     register int pos;
     99     while(!q.empty())
    100     {
    101         int u = q.front();
    102         q.pop();
    103         b3[u] = 0;
    104         for(pos = head3[u];pos;pos = edge3[pos].next)
    105         {
    106             int v = edge3[pos].v;
    107             if(d3[v] > d3[u] + edge3[pos].w)
    108             {
    109                 d3[v] = d3[u] + edge3[pos].w;
    110                 if(!b3[v])
    111                 {
    112                     q.push(v);
    113                     b3[v] = 1;
    114                 }
    115             }
    116         }
    117     }
    118 }
    119 
    120 int main()
    121 {
    122     read(n);read(m);
    123     register int tmp1, tmp2, tmp3, tmp4,i;
    124     for(i = 1;i <= m; ++ i)
    125     {
    126         read(tmp1);read(tmp2);read(tmp3);read(tmp4);
    127         insert1(tmp2, tmp1, tmp3);
    128         insert2(tmp2, tmp1, tmp4);
    129         insert3(tmp1, tmp2, 0);
    130     }
    131     SPFA1();
    132     SPFA2();
    133     for(int i = 1;i <= cnt3;++ i)
    134     {
    135         tmp1 = edge3[i].v;tmp2 = edge3[i].u;
    136         if(d1[tmp1] + edge1[i].w > d1[tmp2]) ++edge3[i].w;
    137         if(d2[tmp1] + edge2[i].w > d2[tmp2]) ++edge3[i].w;
    138     }
    139     SPFA3();
    140     printf("%lld", d3[n]);
    141     return 0;
    142 } 
    View Code
  • 相关阅读:
    Python基础知识2-内置数据结构(上)
    vs code的快捷方式
    vs code配置
    vs code安装
    web浏览器兼容问题
    js正則表達式
    MVC MVP MVVM
    vue-cli(vue脚手架)
    web攻擊
    web前端面試題
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7114976.html
Copyright © 2011-2022 走看看