zoukankan      html  css  js  c++  java
  • NOIP模拟赛 6.29

    2017-6-29 NOIP模拟赛

    Problem 1 机器人(robot.cpp/c/pas)

    【题目描述】

    早苗入手了最新的Gundam模型。最新款自然有着与以往不同的功能,那就是它能够自动行走,厉害吧。

    早苗的新模型可以按照输入的命令进行移动,命令包括‘E’、‘S’、‘W’、‘N’四种,分别对应东南西北。执行某个命令时,它会向对应方向移动一个单位。作为新型机器人,它可以执行命令串。对于输入的命令串,每一秒它会按命令行动一次。执行完命令串的最后一个命令后,会自动从头开始循环。在0时刻时机器人位于(0,0)。求T秒后机器人所在位置坐标。

    【输入格式】

    1行:一个字符串,表示早苗输入的命令串,保证至少有1个命令

    2行:一个正整数T

    【输出格式】

    2个整数,表示T秒时,机器人的坐标。

    【样例输入】

    NSWWNSNEEWN

    12

    【样例输出】

    -1 3

    【数据范围】

    对于60%的数据 T<=500,000 且命令串长度<=5,000

    对于100%的数据 T<=2,000,000,000 且命令串长度<=5,000

    【注意】

    向东移动,坐标改变改变为(X+1,Y);

    向南移动,坐标改变改变为(X,Y-1);

    向西移动,坐标改变改变为(X-1,Y);

    向北移动,坐标改变改变为(X,Y+1);

    水过。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring> 
     5 #include <algorithm>
     6 #include <vector>
     7 #include <queue>
     8 inline void read(long long &x){x = 0;char ch = getchar();char c = ch;while(ch > '9' || ch < '0')c = ch, ch = getchar();while(ch >= '0' && ch <= '9')x = x * 10 + ch - '0', ch = getchar();}
     9 inline int max(int a, int b){return a > b ? a : b;}
    10 inline int min(int a, int b){return a < b ? a : b;}
    11 inline void swap(int &a, int &b){int tmp = a;a = b;b = tmp;}
    12 
    13 const int INF = 0x3f3f3f3f;
    14 const int MAXN = 5000 + 10;
    15 
    16 char s[MAXN];
    17 long long t;
    18 long long len, xx, yy;
    19 long long x,y;
    20 
    21 int main()
    22 {
    23     scanf("%s", s + 1);
    24     read(t);
    25     len = strlen(s + 1);
    26     if(t < len)
    27     {
    28         for(register int i = 1;i <= t;++ i)
    29         {
    30             if(s[i] == 'E')++ xx;
    31             else if(s[i] == 'S')--yy;
    32             else if(s[i] == 'W')--xx;
    33             else ++yy;
    34         }
    35         x = xx;
    36         y = yy;
    37     }
    38     else
    39     {
    40         for(register int i = 1;i <= len;++ i)
    41         {
    42             if(s[i] == 'E')++ xx;
    43             else if(s[i] == 'S')--yy;
    44             else if(s[i] == 'W')--xx;
    45             else ++yy;
    46         }
    47         int group = t / len;
    48         x = xx * group;
    49         y = yy * group;
    50         group = t % len;
    51         for(register int i = 1;i <= group;i ++)
    52         {
    53             if(s[i] == 'E')++ x;
    54             else if(s[i] == 'S')--y;
    55             else if(s[i] == 'W')--x;
    56             else ++y;
    57         }
    58     }
    59     printf("%lld %lld", x, y);
    60     return 0;
    61 }
    View Code

    Problem 2 数列(seq.cpp/c/pas)

    【题目描述】

    a[1]=a[2]=a[3]=1

    a[x]=a[x-3]+a[x-1]  (x>3)

    a数列的第n项对1000000007(10^9+7)取余的值。

    【输入格式】

    第一行一个整数T,表示询问个数。 

    以下T行,每行一个正整数n。

    【输出格式】

    每行输出一个非负整数表示答案。

    【样例输入】

    3

    6

    8

    10

    【样例输出】

    4

    9

    19

    【数据范围】

    对于30%的数据 n<=100;

    对于60%的数据 n<=2*10^7;

    对于100%的数据 T<=100,n<=2*10^9;

     

    矩阵快速幂。

    构造矩阵:

    1 1 0 0

    0 1 0 1

    0 1 0 0

    0 0 1 0

    an

    a(n - 2)

    a(n - 3)

    a(n - 4)

     

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring> 
      5 #include <algorithm>
      6 #include <vector>
      7 #include <queue>
      8 inline void read(long long &x){x = 0;char ch = getchar();char c = ch;while(ch > '9' || ch < '0')c = ch, ch = getchar();while(ch >= '0' && ch <= '9')x = x * 10 + ch - '0', ch = getchar();}
      9 inline int max(int a, int b){return a > b ? a : b;}
     10 inline int min(int a, int b){return a < b ? a : b;}
     11 inline void swap(int &a, int &b){int tmp = a;a = b;b = tmp;}
     12 
     13 const int INF = 0x3f3f3f3f;
     14 const int MOD = 1000000007;
     15 
     16 long long s1[10][10];
     17 long long s2[10];
     18 long long ans[10][10];
     19 long long base[10][10];
     20 long long tmp[10][10];
     21 
     22 long long pow(int b)
     23 {
     24     for(int i = 1;i <= 4;i ++)
     25     {
     26         ans[i][i] = 1;
     27         for(int j = 1;j <= 4;j ++)
     28         {
     29             base[i][j] = s1[i][j] % MOD;
     30         }
     31     }
     32     while(b)
     33     {
     34         
     35         if(b & 1)
     36         {
     37             for(int i = 1;i <= 4;++ i)
     38             {
     39                 for(int j = 1;j <= 4;++ j)
     40                 {
     41                     tmp[i][j] = ans[i][j] % MOD;
     42                 }
     43             }
     44             //    ans *= base;
     45             memset(ans, 0, sizeof(ans));
     46             for(int k = 1;k <= 4;++ k)
     47             {
     48                 for(int i = 1;i <= 4; ++ i)
     49                 {
     50                     for(int j = 1;j <= 4;++ j)
     51                     {
     52                         ans[i][j] += ((tmp[i][k] % MOD) * (base[k][j] % MOD)) % MOD;
     53                     }
     54                 }
     55             }
     56         }
     57         
     58         
     59         for(int i = 1;i <= 4;i ++)
     60         {
     61             for(int j = 1;j <= 4;j ++)
     62             {
     63                 tmp[i][j] = base[i][j] % MOD;
     64             }
     65         }
     66         memset(base, 0, sizeof(base));
     67         for(int k = 1;k <= 4;++ k)
     68         {
     69             for(int i = 1;i <= 4; ++ i)
     70             {
     71                 for(int j = 1;j <= 4;++ j)
     72                 {
     73                     base[i][j] += ((tmp[i][k] % MOD) * (tmp[k][j] % MOD)) % MOD;
     74                 }
     75             }
     76         }
     77         //base = base * base;
     78         b >>= 1;
     79     }
     80     return ((((ans[1][1]%MOD) * (s2[1]%MOD) % MOD) + ((ans[1][2]%MOD) * (s2[2]%MOD) % MOD))%MOD + (((ans[1][3]%MOD) *(s2[3]%MOD)) % MOD + ((ans[1][4]%MOD) * (s2[4]%MOD)) % MOD)%MOD) % MOD;
     81 }
     82 
     83 long long n,t;
     84 
     85 int main()
     86 {
     87     read(t);
     88     while(t)
     89     {
     90         memset(base, 0, sizeof(base));
     91         memset(tmp, 0, sizeof(tmp));
     92         memset(ans, 0, sizeof(ans));
     93         read(n);
     94         if(n == 1 || n == 2 || n == 3)
     95         {
     96             printf("1
    ");
     97             -- t;
     98             continue;
     99         }
    100         else if(n == 4)
    101         {
    102             printf("2
    ");
    103             -- t;
    104             continue;
    105         }
    106         else if(n == 5)
    107         {
    108             printf("3
    ");
    109             -- t;
    110             continue;
    111         }
    112         s1[1][1] = 1;s1[1][2] = 1;s1[1][3] = 0;s1[1][4] = 0;
    113         s1[2][1] = 0;s1[2][2] = 1;s1[2][3] = 0;s1[2][4] = 1;
    114         s1[3][1] = 0;s1[3][2] = 1;s1[3][3] = 0;s1[3][4] = 0;
    115         s1[4][1] = 0;s1[4][2] = 0;s1[4][3] = 1;s1[4][4] = 0;
    116         s2[1] = 3;s2[2] = 1;s2[3] = 1;s2[4] = 1;
    117         long long a = pow(n - 5);
    118         printf("%lld
    ", a % MOD);
    119         -- t;
    120     } 
    121     return 0;
    122 }
    View Code

    Problem 3 虫洞(holes.cpp/c/pas)

    【题目描述】

    N个虫洞,M条单向跃迁路径。从一个虫洞沿跃迁路径到另一个虫洞需要消耗一定量的燃料和1单位时间。虫洞有白洞和黑洞之分。设一条跃迁路径两端的虫洞质量差为delta。

    1.从白洞跃迁到黑洞,消耗的燃料值减少delta,若该条路径消耗的燃料值变为负数的话,取为0。

    2.从黑洞跃迁到白洞,消耗的燃料值增加delta。

    3.路径两端均为黑洞或白洞,消耗的燃料值不变化。

    作为压轴题,自然不会是如此简单的最短路问题,所以每过1单位时间黑洞变为白洞,白洞变为黑洞。在飞行过程中,可以选择在一个虫洞停留1个单位时间,如果当前为白洞,则不消耗燃料,否则消耗s[i]的燃料。现在请你求出从虫洞1到N最少的燃料消耗,保证一定存在1到N的路线。

    【输入格式】

    1行:2个正整数N,M

    2行:N个整数,第i个为0表示虫洞i开始时为白洞,1表示黑洞。

    3行:N个整数,第i个数表示虫洞i的质量w[i]。

    4行:N个整数,第i个数表示在虫洞i停留消耗的燃料s[i]。

    5..M+4行:每行3个整数,u,v,k,表示在没有影响的情况下,从虫洞u到虫洞v需要消耗燃料k。

    【输出格式】

    一个整数,表示最少的燃料消耗。

    【样例输入】

    4 5

    1 0 1 0

    10 10 100 10

    5 20 15 10

    1 2 30

    2 3 40

    1 3 20

    1 4 200

    3 4 200

    【样例输出】

    130

    【数据范围】

    对于30%的数据: 1<=N<=100,1<=M<=500

    对于60%的数据: 1<=N<=1000,1<=M<=5000

    对于100%的数据: 1<=N<=5000,1<=M<=30000

                      其中20%的数据为1<=N<=3000的链

                      1<=u,v<=N, 1<=k,w[i],s[i]<=200

    【样例说明】

    按照1->3->4的路线。

     

    不难发现,无论时间怎样变化,两个点的相对颜色总是不变(即总是同色或异色)

    把一个点拆成两个点,分别代表白、黑,记为i,i'

    每一s黑白互换,因此当i->j,权值为w时,我们令i->j',权值为w

    又由于我们可以在某一个点上停留一个单位时间,从而使得点黑白互换,因此应让i->i'和i'->i连边即可。而又由于任何节点相对颜色不变,我们可以知道走这条边到达i'(i)后仍是合法的。

    这样建图跑SPFA即可

     

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring> 
      5 #include <algorithm>
      6 #include <vector>
      7 #include <queue>
      8 inline void read(int &x){x = 0;char ch = getchar();char c = ch;while(ch > '9' || ch < '0')c = ch, ch = getchar();while(ch >= '0' && ch <= '9')x = x * 10 + ch - '0', ch = getchar();}
      9 inline int max(int a, int b){return a > b ? a : b;}
     10 inline int min(int a, int b){return a < b ? a : b;}
     11 inline void swap(int &a, int &b){int tmp = a;a = b;b = tmp;}
     12  
     13 const int INF = 0x3f3f3f3f;
     14 const int MAXN = 1000000;
     15 const int MAXM = 3000000;
     16 
     17 int n,m;
     18 int bw[MAXN << 1],weight[MAXN],s[MAXN];
     19 int tmp1, tmp2, tmp3;
     20 
     21 struct Edge
     22 {
     23     int u,v,next,w;
     24 }edge[MAXM];
     25 int head[MAXN << 1],cnt;
     26 void insert(int a, int b, int c){edge[++cnt] = Edge{a, b, head[a], c};head[a] = cnt;}
     27 
     28 std::queue<int> q;
     29 int b[MAXN << 1],d[MAXN];
     30 
     31 void SPFA()
     32 {
     33     memset(d, 0x3f, sizeof(d));
     34     q.push(2);d[2] = 0;
     35     b[2] = true;
     36     register int u,v;
     37     while (!q.empty())
     38     {
     39         u = q.front();
     40         q.pop();
     41         b[u] = false;
     42         for (int pos = head[u];pos;pos = edge[pos].next)
     43         {
     44             v = edge[pos].v;
     45             if (d[v] > d[u] + edge[pos].w)
     46             {
     47                 d[v] = d[u] + edge[pos].w;
     48                 if (!b[v])
     49                 {
     50                     b[v] = true;
     51                     q.push(v);
     52                 }
     53             }
     54         }
     55     }
     56 }
     57 
     58 int main()
     59 {
     60     read(n);read(m);
     61     
     62     for (register int i = 1;i <= n;++ i)
     63     {
     64         read(bw[i << 1]);
     65         bw[i << 1 | 1] = 1 ^ bw[i << 1];
     66     }
     67     
     68     for (register int i = 1;i <= n;++ i)
     69     {
     70         read(weight[i]);
     71     }
     72     
     73     for (register int i = 1;i <= n;++ i)
     74     {
     75         read(s[i]);
     76         int w = s[i];
     77         if (!bw[i << 1])
     78             insert(i << 1, i << 1 | 1, 0),insert(i << 1 | 1, i << 1, s[i]); 
     79         else 
     80             insert(i << 1, i << 1 | 1, s[i]),insert(i << 1 | 1, i << 1, 0); 
     81     }
     82     
     83     for (register int i = 1;i <= m;++ i)
     84     {
     85         read(tmp1);read(tmp2);read(tmp3);
     86         int w1 = 0,w2 = 0;
     87         
     88         //0 白  1  黑
     89         
     90         //相同 不变化 
     91         
     92         if (bw[tmp1 << 1] == bw[tmp2 << 1])
     93             w1 = w2 = tmp3;
     94             
     95         //0 -> 1  减小weight差 ,负数记为0
     96         
     97         if (bw[tmp1 << 1] == 0 && bw[tmp2 << 1] == 1)
     98             w1 = tmp3 - abs(weight[tmp1] - weight[tmp2]);
     99         if (bw[tmp1 << 1 | 1] == 0 && bw[tmp2 << 1 | 1] == 1)
    100             w2 = tmp3 - abs(weight[tmp1] - weight[tmp2]);
    101             
    102         //1 -> 0 增加weight差
    103         
    104         if (bw[tmp1 << 1] == 1 && bw[tmp2 << 1] == 0)
    105             w1 = tmp3 + abs(weight[tmp1] - weight[tmp2]);
    106         if (bw[tmp1 << 1 | 1] == 1 && bw[tmp2 << 1 | 1] == 0)
    107             w2 = tmp3 + abs(weight[tmp1] - weight[tmp2]);
    108             
    109         if (w1 < 0)
    110             w1 = 0;
    111         if (w2 < 0)
    112             w2 = 0;
    113             
    114         insert(tmp1 << 1, tmp2 << 1 | 1, w1);
    115         insert(tmp1 << 1 | 1, tmp2 << 1, w2);
    116     }
    117     
    118     SPFA();
    119     
    120     printf("%d", min(d[n << 1], d[n << 1 | 1]));
    121     return 0;
    122 }
    View Code

    第一次AK,开森~

    题怪简单

  • 相关阅读:
    调查:秋色园QBlog 博客开源不开源,您的建议是?
    CYQ.Data 数据框架 V2.0 版本 开放源码 继续开源之路
    CYQ.Data 数据框架 V3.0 版本 开放源码下载有[CYQ.Blog(秋色园QBlog) 完全开放所有源码]
    秋色园QBlog技术原理解析:性能优化篇:用户和文章计数器方案(十七)
    【视频】配置信息管理 的 使用方法(六):实现添加、修改、查询
    【视频】配置信息管理 的 使用方法(五):配置程序之列表、分页控件、按钮
    自然框架的声明
    【自然框架】稳定版的Demo——看点二:权限,权限过滤与验证。
    见到了“公司”定义一个Company类,那么见到了“字段”是不是也可定义一个Column类?
    《锋利的jquery》实例源码下载
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7093198.html
Copyright © 2011-2022 走看看