2019-05-03
传送门------第一题
传送门------第二题
传送门------第三题
题目描述
早苗入手了最新的Gundam模型。最新款自然有着与以往不同的功能,那就是它能够自动行走,厉害吧。
早苗的新模型可以按照输入的命令进行移动,命令包括‘E’、‘S’、‘W’、‘N’四种,分别对应东南西北。执行某个命令时,它会向对应方向移动一个单位。作为新型机器人,它可以执行命令串。对于输入的命令串,每一秒它会按命令行动一次。执行完命令串的最后一个命令后,会自动从头开始循环。在0时刻时机器人位于(0,0)。求T秒后机器人所在位置坐标。
早苗的新模型可以按照输入的命令进行移动,命令包括‘E’、‘S’、‘W’、‘N’四种,分别对应东南西北。执行某个命令时,它会向对应方向移动一个单位。作为新型机器人,它可以执行命令串。对于输入的命令串,每一秒它会按命令行动一次。执行完命令串的最后一个命令后,会自动从头开始循环。在0时刻时机器人位于(0,0)。求T秒后机器人所在位置坐标。
输入
第1行:一个字符串,表示早苗输入的命令串,保证至少有1个命令 ;
第2行:一个正整数T。
第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
向东移动,坐标改变改变为(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\n",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。
以下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.从白洞跃迁到黑洞,消耗的燃料值减少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。
第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
按照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 }
总结:
这次考试的三道题目都比较的基础,没有什么需要大量码字的东西,但还是没考好说明对于一些基础的加速算法还不是很理解,对于一些很基础的题目还是没有一眼看出解法,还是要多刷题,多总结。