2019-05-03

传送门------第一题

传送门------第二题

传送门------第三题

题目描述

早苗入手了最新的Gundam模型。最新款自然有着与以往不同的功能,那就是它能够自动行走,厉害吧。  
早苗的新模型可以按照输入的命令进行移动,命令包括‘E’、‘S’、‘W’、‘N’四种,分别对应东南西北。执行某个命令时,它会向对应方向移动一个单位。作为新型机器人,它可以执行命令串。对于输入的命令串,每一秒它会按命令行动一次。执行完命令串的最后一个命令后,会自动从头开始循环。在0时刻时机器人位于(0,0)。求T秒后机器人所在位置坐标。 

输入

第1行:一个字符串,表示早苗输入的命令串,保证至少有1个命令 ; 
第2行:一个正整数T。 

输出

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

样例输入 Copy

NSWWNSNEEWN
12

样例输出 Copy

-1 3

提示

注意:  
向东移动,坐标改变改变为(X+1,Y);  
向南移动,坐标改变改变为(X,Y-1);  
向西移动,坐标改变改变为(X-1,Y);  
向北移动,坐标改变改变为(X,Y+1);  

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

来源/分类

NOIP模拟赛 
 
 

思路:

考试一开始看到这题,哇,模拟啊,如果出现循环就只找一次然后乘一下次数就行了,然后也只有字符串比较烦人了。。。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 string w;
 6 long long  n;
 7 long long  len;
 8 long long  x,y;
 9 int main()
10 {
11     getline(cin,w);
12     cin>>n;
13     len=w.size();
14     /*for(int i=1;i<=len;i++)
15     {
16         printf("%c
",w[i]);
17     }*/
18     //int len2=len+1;
19     long long int tot=n/len;//ÕûµÄ 
20     long long int sum=n%len;//ÓàµÄ 
21     //cout<<len<<endl;
22     //cout<<tot<<endl;
23     //cout<<sum<<endl;
24     if(n<len)
25     {
26         for(int i=0;i<n;i++)
27         {
28             if(w[i]=='E')
29             {
30                 x++;
31             }
32             if(w[i]=='S')
33             {
34                 y--;
35             }
36             if(w[i]=='W')
37             {
38                 x--;
39             }
40             if(w[i]=='N')
41             {
42                 y++;
43             }
44         }
45         cout<<x<<" "<<y<<endl;
46         //cout<<1111<<endl;
47         return 0;
48     }
49     else
50     {
51         for(int i=0;i<=len;i++)
52         {
53             if(w[i]=='E')
54             {
55                 x++;
56             }
57             if(w[i]=='S')
58             {
59                 y--;
60             }
61             if(w[i]=='W')
62             {
63                 x--;
64             }
65             if(w[i]=='N')
66             {
67                 y++;
68             }
69         }
70         x*=tot;
71         y*=tot;
72         for(int i=0;i<sum;i++)
73         {
74             if(w[i]=='E')
75             {
76                 x++;
77             }
78             if(w[i]=='S')
79             {
80                 y--;
81             }
82             if(w[i]=='W')
83             {
84                 x--;
85             }
86             if(w[i]=='N')
87             {
88                 y++;
89             }
90         }
91         cout<<x<<" "<<y<<endl;
92         //cout<<222222<<endl;
93         return 0;
94     }
95     return 0;
96 }
 

这题真的水

 
 

第二题:

题目描述

a[1]=a[2]=a[3]=1  
a[x]=a[x-3]+a[x-1] (x>3)  
求a数列的第n项对1000000007(109+7)取余的值。 

输入

第一行一个整数T,表示询问个数。  
以下T行,每行一个正整数n。 

输出

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

样例输入 Copy

3
6
8
10

样例输出 Copy

4
9
19

提示

对于30%的数据 n<=100;  
对于60%的数据 n<=2*107;  
对于100%的数据 T<=100,n<=2*109 

思路:

这题看到描述时,脑子里的第一反应就是递推加记忆化,然后看到了样例,恩,没错,然后看到了数据范围,恩......,然后.......就没了。

这个109是在逗我吗?这什么数组存的下呀!滚动数组?不会打。。。。

在这时,我想起了几个月前搞斐波那契数列时看到的好体---->传送门,这和那题的数据不是差不多的吗?我记得当时去博客园某位大佬的博客看的是矩阵乘法,但是。。。还是不会啊。。。

周二晚上听大佬一说,感觉好简单,就动手打了一下,发现也并未有这么好打,小细节还是很多的。

代码:

 

后话:

考完后去洛谷一看竟然还是模板。。。。

第三题:

题目描述

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。 

输出

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

样例输入 Copy

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

样例输出 Copy

130

提示

样例解释: 
按照1->3->4的路线。  

对于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 

来源/分类

NOIP模拟赛 
 

思路:

考场上因为太懒,一看到这么多条件立刻放弃,考完试看大佬谈论这题如何如何水,不竟有些后悔,周二讲题目时也是如此省略,不仅是DP,分层图也可以做,细细一想好像分层图比DP还要好跑一点,主要的建边后,就是裸的SPFA(真的是一点都没改),而分层图的建边其实也挺好理解的。。。

 

标称

  1 #include<iostream>
  2 #include<queue>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<cmath>
  6 using namespace std;
  7 #define max(a,b) a>b?a:b
  8 #define min(a,b) a<b?a:b
  9 const int maxn=1e6+10;
 10 struct node
 11 {
 12     int value;
 13     int to;
 14     int next;
 15 }way[maxn];
 16 int tot;
 17 int n;
 18 int m;
 19 int v[maxn];
 20 int s[maxn];
 21 int dis[maxn];
 22 int k[maxn];
 23 bool vis[maxn];
 24 bool f[maxn];
 25 int head[maxn];
 26 
 27 int add(int x,int y,int w)
 28 {
 29     way[++tot].next=head[x];
 30     way[tot].to=y;
 31     way[tot].value=w;
 32     head[x]=tot;
 33 }
 34 
 35 int work()
 36 {
 37     cin>>n>>m;
 38     int x,y,w;
 39     int d;
 40     for(int i=1;i<=n;i++)
 41     {
 42         scanf("%d",f+i);
 43     }
 44     for(int i=1;i<=n;i++)
 45     {
 46         scanf("%d",v+i);
 47     }
 48     for(int i=1;i<=n;i++)
 49     {
 50         scanf("%d",s+i);
 51     }
 52     for(int i=1;i<=m;i++)
 53     {
 54         cin>>x>>y>>w;
 55         if(f[x]==f[y])
 56         {
 57             add(x,y+n,w);
 58             add(x+n,y,w);
 59         }
 60         else
 61         {
 62             d=abs(v[x]-v[y]);
 63             if(f[x]==0)
 64             {
 65                 add(x,y+n,max(0,w-d));
 66                 add(x+n,y,max(0,w+d));
 67             }
 68             else
 69             {
 70                 add(x,y+n,max(0,w+d));
 71                 add(x+n,y,max(0,w-d));
 72             }
 73         }
 74     }
 75     for(int i=1;i<=n;i++)
 76     {
 77         if(f[i])
 78         {
 79             add(i,i+n,s[i]);
 80             add(i+n,i,0);
 81         }
 82         else
 83         {
 84             add(i,i+n,0);
 85             add(i+n,i,s[i]);
 86         }
 87     }
 88 }
 89 
 90 int spfa()
 91 {
 92     queue<int > q;
 93     memset(dis,0x3f,sizeof(dis));
 94     dis[1]=0;
 95     memset(vis,0,sizeof(vis));
 96     vis[1]=true;
 97     q.push(1);
 98     while(!q.empty())
 99     {
100         int x=q.front();
101         q.pop();
102         vis[x]=false;
103         for(int i=head[x];i;i=way[i].next)
104         {
105             if(dis[x]+way[i].value<dis[way[i].to])
106             {
107                 dis[way[i].to]=dis[x]+way[i].value;
108                 if(!vis[way[i].to])
109                 {
110                     q.push(way[i].to);
111                     vis[way[i].to]=true;
112                 }
113             }
114         }
115     }
116     return min(dis[n],dis[2*n]);
117 }
118 int main()
119 {
120     work();
121 
122     int ans=spfa();
123     cout<<ans<<endl;
124     return 0;
125 }

 总结:

这次考试的三道题目都比较的基础,没有什么需要大量码字的东西,但还是没考好说明对于一些基础的加速算法还不是很理解,对于一些很基础的题目还是没有一眼看出解法,还是要多刷题,多总结。

原文地址:https://www.cnblogs.com/2529102757ab/p/10828337.html