比赛时我们队一个小时不到切了5个水题,最后AC的只有六个题(B D E F I M)K题思路完全正确,但是队友用int 输入,最后一组样例死活过不去,还以为是自己思路不对,赛后改成ull直接过掉也醉了。L题线段树全程卡bug,WA到死,涵哥给的题解说是平衡树裸题,完全不会平衡树。H题裸的搜索为什么没人做啊,全程跟榜读都没有读。赛后补题 A C G 目前不会,只能先把涵哥的题解贴上去

A wyh的曲线

时间限制:C/C++ 1秒,其他语言2秒

空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

给你三组数列,分别为

现在给你一个式子:

然后我们可以将这个函数画在一个xoy直角坐标系下,x的范围为[0,100],当然我们可以得到一条曲线,现在你们涵哥让你们求出这个曲线的长度,结果保留两位小数

输入描述:

单组输入:

每组测试数据第一行输入一个整数n。

接下来n行,每行3个数代表

Data limit:

输出描述:

对于每组测试数据,输出对应答案,结果保留两位小数
示例1

输入

3 
1 2 3 
4 5 6 
7 8 9

输出

215.56

完全不知道怎么积分,学完再补一下

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 double a[55],b[55],k[55];
 4 double fs(double x,int s)
 5 {
 6     if(k[s]*(x-a[s])*(x-a[s])+b[s]>100)
 7         return 0;
 8     return k[s]*(2*x-2*a[s]);
 9 }
10 int n;
11 double ges(double x)
12 {
13     double ans=100,res=0;
14     for(register int s=1; s<=n; s++)
15         if(k[s]*(x-a[s])*(x-a[s])+b[s]<ans)
16             res=fs(x,s),ans=k[s]*(x-a[s])*(x-a[s])+b[s];
17     return res;
18 }
19 double fun(double x)
20 {
21     return sqrt(1+ges(x)*ges(x));
22 }
23 double Simpson(double l,double r)
24 {
25     return (fun(l)+fun(r)+4*fun((l+r)/2))/6*(r-l);
26 }
27 double asr(double l,double r,double last,int deep,double eps)
28 {
29     double m=(l+r)/2,a,b,ans;
30     a=Simpson(l,m);
31     b=Simpson(m,r);
32     ans=a+b;
33     if(deep<10||fabs(ans-last)>eps)
34         ans=asr(l,m,a,deep+1,eps/2)+asr(m,r,b,deep+1,eps/2);
35     return ans;
36 }
37 int main()
38 {
39     int t;
40     double ans=1e9;
41     scanf("%d",&n);
42     for(int s=1; s<=n; s++)
43         scanf("%lf%lf%lf",k+s,a+s,b+s);
44     ans=asr(0,100,Simpson(0,100),0,1e-4);
45     printf("%.2fn",ans);
46 }

 

 

B wyh的矩阵

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

给你一个n*n矩阵,按照顺序填入1到n*n的数,例如n=5,该矩阵如下 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

现在让你连接相邻两条边的中点,然后只保留他们围成封闭图形区域的数字,那么这个矩阵变为

 

 

3

 

 

 

7

8

9

 

11

12

13

14

15

 

17

18

19

 

 

 

23

 

 

现在你们涵哥让你求变化后的矩阵的所有元素的和为多少

输入描述:

输入第一行一个整数T(1<=T<=100)
接下来有T组测试数据,每组测试数据输入一个整数n(3<=n<=10000)
保证输入的n为奇数

输出描述:

对于每组测试数据,输出对应答案
示例1

输入

2
3
5

输出

25
169

语法题没什么可说的,直接上代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int main() {
 4     ios::sync_with_stdio(false);
 5     cin.tie(NULL);
 6     int t, n, i, j, k;
 7     unsigned long long int ans;
 8     scanf("%d", &t);
 9     while (t--) {
10         scanf("%d", &n);
11         ans = 0;
12         for (i = 0; i <= n / 2; i++)
13             for (j = n / 2 - i; j <= n / 2 + i; j++)
14                 ans += i * n + j + 1;
15         for (k = 1; i < n; i++, k++)
16             for (j = k; j < n - k; j++) {
17                 //cout << i * n + j + 1 << endl;
18                 ans += i * n + j + 1;
19             }
20         cout << ans << endl;
21     }
22     return 0;
23 }

 

C wyh的商机

时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

一天,你们wyh学长和你们zhl学长玩一个游戏,这个游戏规则是这样的 

给你n个城市,保证这n个城市之间都只有一条道路可以到达。 

有一件物品,在所有城市中都是一样的,但是由于各个城市的经济发展不同,导致每个城市对于这件物品销售的价格不同。

游戏一共进行Q轮。 

每轮给你2个点s和t,其中s代表起点,t代表终点。 

对于每一个城市都可以选择买这个物品,如果手里有这个物品的话,也可以选择卖掉这个物品,对于同一个城市来说,买和卖的价格是一样的,每一个城市只能买一件物品

现在,你们wyh学长和zhl学长都需要找到一个方案,使得从起点走到终点的时候盈利最多,请你帮助帮助他们吧 

输入描述:

每个测试文件中都只有一组测试数据

输入第一行一个整数n(1<=n<=50000),代表有n个城市

第二行输入n个数,代表每个城市对于这件物品的价格wi(1<=wi<=50000)

接下来有n-1行,每行2个数a和b,代表a到b之间有一条路

接下来输入一个数Q(1<=Q<=50000)

接下来Q行,每行2个数s和t

输出描述:

对于每组测试数据,输出对应答案,如果从起点到终点不能盈利的话,输出0
示例1

输入

4
1 
5 
3 
2
1 3
3 2
3 4
9
1 2
1 3
1 4
2 3
2 1
2 4
3 1
3 2
3 4

输出

4
2
2
0
0
0
0
2
0
LCA 并不会。

 

D wyh的迷宫

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

给你一个n*m的迷宫,这个迷宫中有以下几个标识: 

s代表起点 

t代表终点 

x代表障碍物 

.代表空地 

现在你们涵哥想知道能不能从起点走到终点不碰到障碍物(只能上下左右进行移动,并且不能移动到已经移动过的点)。

输入描述:

输入第一行一个整数T(1<=T<=10)
接下来有T组测试数据,对于每一组测试数据,第一行输入2个数n和m(1<=n,m<=500)
接下来n行,每行m个字符代表这个迷宫,每个字符都是上面4个中的一种
数据保证只有一个起点和一个终点

输出描述:

对于每一组测试数据,如果可以的话输出YES,不可以的话输出NO
示例1

输入

1
3 5
s...x
x...x
...tx

输出

YES
裸 BFS 详细解题可以参照 《挑战程序设计》34页
 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int t, n, m;
 6 char maze[500][502];
 7 bool vis[500][500];
 8 
 9 struct Point
10 {
11     int x;
12     int y;
13 };
14 
15 bool BFS(int x, int y) {
16     queue<Point> que;
17     Point p;
18     vis[x][y] = true;
19     que.push({x, y});
20     while (!que.empty()) {
21         p = que.front();
22         que.pop();
23         if (maze[p.x][p.y] == 't')
24             return true;
25         if (p.x + 1 < n && vis[p.x + 1][p.y] == false && maze[p.x + 1][p.y] != 'x') {
26             que.push({p.x + 1, p.y});
27             vis[p.x + 1][p.y] = true;
28         }
29         if (p.y + 1 < m && vis[p.x][p.y + 1] == false && maze[p.x][p.y + 1] != 'x') {
30             que.push({p.x, p.y + 1});
31             vis[p.x][p.y + 1] = true;
32         }
33         if (p.x - 1 >= 0 && vis[p.x - 1][p.y] == false && maze[p.x - 1][p.y] != 'x') {
34             que.push({p.x - 1, p.y});
35             vis[p.x - 1][p.y] = true;
36         }
37         if (p.y - 1 >= 0 && vis[p.x][p.y - 1] == false && maze[p.x][p.y - 1] != 'x') {
38             que.push({p.x, p.y - 1});
39             vis[p.x][p.y - 1] = true;
40         }
41     }
42     return false;
43 }
44 
45 int main(void) {
46     ios::sync_with_stdio(false);
47     cin.tie(NULL);
48     int i, j;
49     scanf("%d", &t);
50     while (t--) {
51         scanf("%d %d", &n, &m);
52         memset(vis, 0, sizeof(vis));
53         getchar();
54         for (i = 0; i < n; i++)
55             gets(maze[i]);
56         for (i = 0; i < n; i++)
57             for (j = 0; j < m; j++)
58                 if (maze[i][j] == 's') {
59                     if (BFS(i, j) == true)
60                         printf("YESn");
61                     else
62                         printf("NOn");
63                     goto BREAKOUT;
64                 }
65                 BREAKOUT:;
66     }
67     return 0;
68 }

E wyh的阶乘

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

这个问题很简单,就是问你n的阶乘末尾有几个0?

输入描述:

输入第一行一个整数T(1<=T<=100),代表测试组数
接下来T行,每行一个数n(1<=n<=10^9)

输出描述:

对于每组测试数据,输出对应答案
示例1

输入

5
1
2
3
4
5

输出

0
0
0
0
1
比赛时用c++打标到20以为是5个一组依次增加,交上去WA了,用Python打到100发现是循环除以5加商。
题解:
这个题实际上就是求有多少个5的因子,因为要想末尾出现0,必须要有2*5,那么对于阶乘来说,5的个数肯定会比2的个数少,所以直接找有多少个5的根数就可以了
 1 #include <iostream>
 2 using namespace std;
 3 int slove(int n){
 4     int tot= 0;
 5     while(n > 0){
 6         tot += n / 5;
 7         n = n / 5;
 8     }
 9     return tot;
10 }
11 int main(){
12     int tot;
13     cin>>tot;
14     while(tot--){
15         int n;
16         cin>>n;
17         int ans;
18         ans=slove(n);
19         cout<<ans<<endl;
20     }
21     return 0;
22 }

F wyh的集合

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

你们wyh学长给你n个点,让你分成2个集合,然后让你将这n个点进行两两连接在一起,连接规则是这样的 

1. 连接的两个点必须在不同的两个集合 

2. 一个集合内部任意两个点之间不能相连 

现在,wyh学长需要让你将这n个点任意分成2个集合之后,最多能连接多少条边? 

输入描述:

输入第一行一个整数T(1<=T<=100000)
接下来T组测试数据,每组测试数据输入一个整数n(1<=n<=100000)

输出描述:

对于每组测试数据,输出对应答案
示例1

输入

4
0
1
2
4

输出

0
0
1
4

说明

对于4的情况,设4个点为A,B,C,D
第一个集合元素为 A,B
第二个集合元素为C,D
连接的边为AC,AD,BC,BD
此时为最大情况,所以答案为4

题面说的挺高大上的,其实就是求平均数相乘一下因为尽量保证两个集合边数尽可能接近,如果一个集合有n/2条边,另外一个集合就是n-n/2条边,相乘就是结果
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int main(void) {
 4     ios::sync_with_stdio(false);
 5     cin.tie(NULL);
 6     unsigned long long int ans;
 7     int t, n;
 8     scanf("%d", &t);
 9     while (t--) {
10         scanf("%d", &n);
11         if (n < 2) {
12             cout << 0 << endl;
13             continue;
14         }
15         else if (n % 2 == 0)
16             ans = (n / 2) * (n / 2);
17         else
18             ans = (n / 2 + 1) * (n / 2);
19         cout << ans << endl;
20     }
21     return 0;
22 }

G wyh的考核

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

wyh非常喜欢lol游戏,一天,他听说学校要选拔lol队员,他非常高兴的就去了,选拔规则是,一共有N个评委,每个评委根据线上对线能力和打团能力给出一个[0,M]之间的一个整数作为分数,然后取平均值,wyh学长非常好奇,他想知道有多少种这样的情况: 

平均分等于其中某一位评委给的分数

例如2个评委,给打的分数都是1分,那么此时平均分是1分,即等于第一个评委的分数,又等于第二个评委的分数,这样答案是2 

但是由于每个评委打的分都是在[0,M]之间,所以会有很多种情况。 

现在请你帮助你们wyh学长数一下有多少种这样的情况,由于结果会很大,请你对1000000007取余 

输入描述:

输入第一行一个整数T(1<=T<=110)
接下来有T组测试数据,对于每组测试数据输入2个数n和M(2<=n<=60,1<=M<=200),代表有n个评委,每个评委的分数都在[0,M]之间的一个整数

输出描述:

对于每组测试数据,输出对应答案
示例1

输入

1
3 1

输出

6

说明

 

样例解释:

对于样例有以下几种打分情况是符合要求的

 

容斥法

其中每种情况相等的可能性都是三个,比如0分的时候,平均分和第一位、第二位、第三位都相等,所以是3中情况,1的时候也同理,所以答案为6

我们首先枚举均分是多少,然后就知道剩下n-1个人的总分了

然后我们首先考虑剩下的n-1个人里面都选(0-没有上限)的方案数,即隔板法可求

然后再减去一个是(m+1到上限),(n-2)个(0-没有上限)

然后再加上两个个是(m+1到上限),(n-3)个(0-没有上限)

然后再减去三个个是(m+1到上限),(n-4)个(0-没有上限)

……

即容斥一下即可求得答案

效率n*m

 

H wyh的吃鸡

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

 

最近吃鸡游戏非常火,你们wyh学长也在玩这款游戏,这款游戏有一个非常重要的过程,就是要跑到安全区内,否则就会中毒持续消耗血量,我们这个问题简化如下 

假设地图为n*n的一个图,图中有且仅有一块X的联通快代表安全区域,有一个起点S代表缩圈的时候的起点,图中C代表的是车(保证车的数量小于等于100),标记为.的代表空地,可以任意通过,O代表障碍物不能通过。每次没有车的时候2s可以走一个格(只能走自己的上下左右4个方向),有车的话时间为1s走一个格 

现在告诉你最多能坚持的时间为t秒,问你在t秒内(含t秒)能否从s点到达安全区域,能的话输出YES,并且输出最短时间,不能的话输出NO 

输入描述:

输入第一行一个整数T(1<=T<=10)
接下来有T组测试数据,每组测试数据输入2个数n和k(1<=n<=100,1<=k<=10^9)
接下来n行,每行n个字符,代表对应的n*n的地图,每个字符都是上面的一种,并且保证只有一个起点,只有一块安全区域。

输出描述:

对于每组测试数据,先输出能否到达,能的话输出YES,然后换行输出最短时间,如果不能的话直接输出NO
示例1

输入

3
2 3
.X
S.
2 3
.X
SC
2 4
.X
S.

输出

NO
YES
3
YES
4
两次 BFS 第一次不考虑车求最短路,第二次从终点向起点BFS 两次vis的和为坐车的结果
  1 #include <bits/stdc++.h>
  2 #define LL long long
  3 using namespace std;
  4 #define maxn 107
  5 char a[maxn][maxn];
  6 int vis1[maxn][maxn],vis2[maxn][maxn];
  7 int mx[]={0,0,1,-1};
  8 int my[]={1,-1,0,0};
  9 int n;
 10 struct node
 11 {
 12     int x,y,t;
 13 }f,ne;
 14 int t0;
 15 void bfs1(int x,int y)
 16 {
 17     int i,j;
 18     for(i=1;i<=n;i++)
 19         for(j=1;j<=n;j++)
 20             vis1[i][j]=-1;
 21     f.x=x;
 22     f.y=y;
 23     f.t=0;
 24     vis1[x][y]=f.t;
 25     queue <node> q;
 26     q.push(f);
 27     while(!q.empty())
 28     {
 29         f=q.front();
 30         q.pop();
 31         for(i=0;i<4;i++)
 32         {
 33             ne=f;
 34             ne.x+=mx[i];
 35             ne.y+=my[i];
 36             ne.t+=2;
 37             if(ne.x>=1&&ne.x<=n&&ne.y>=1&&ne.y<=n&&a[ne.x][ne.y]!='O'&&vis1[ne.x][ne.y]==-1)
 38             {
 39                 vis1[ne.x][ne.y]=ne.t;
 40                 if(a[ne.x][ne.y]=='X') 
 41                     t0=min(t0,ne.t);
 42                 else 
 43                     q.push(ne);
 44             }
 45         }
 46     }
 47 }
 48 void bfs2()
 49 {
 50     int i,j;
 51     for(i=1;i<=n;i++)
 52         for(j=1;j<=n;j++)
 53             vis2[i][j]=-1;
 54     queue <node> q;
 55     for(i=1;i<=n;i++)
 56     {
 57         for(j=1;j<=n;j++)
 58         {
 59             if(a[i][j]=='X')
 60             {
 61                 f.x=i;
 62                 f.y=j;
 63                 f.t=0;
 64                 vis2[i][j]=f.t;
 65                 q.push(f);
 66             }
 67         }
 68     }
 69     while(!q.empty())
 70     {
 71         f=q.front();
 72         //printf("(%d,%d,%d) ",f.x,f.y,f.t);
 73         q.pop();
 74         for(i=0;i<4;i++)
 75         {
 76             ne=f;
 77             ne.x+=mx[i];
 78             ne.y+=my[i];
 79             ne.t++;
 80             if(ne.x>=1&&ne.x<=n&&ne.y>=1&&ne.y<=n&&a[ne.x][ne.y]!='O'&&vis2[ne.x][ne.y]==-1)
 81             {
 82                 vis2[ne.x][ne.y]=ne.t;
 83                 if(a[ne.x][ne.y]=='C')
 84                 {
 85                     if(vis1[ne.x][ne.y]!=-1)
 86                         t0=min(t0,ne.t+vis1[ne.x][ne.y]);
 87                 }
 88                 q.push(ne);
 89             }
 90         }
 91     }
 92 }
 93 int main()
 94 {
 95     int t;
 96     scanf("%d",&t);
 97     while(t--)
 98     {
 99         int k,i,j,x,y;
100         scanf("%d%d",&n,&k);
101         for(i=1;i<=n;i++)
102         {
103             scanf("%s",a[i]+1);
104             for(j=1;j<=n;j++)
105             {
106                 if(a[i][j]=='S')
107                     x=i,y=j;
108             }
109         }
110         t0=1e9+7;
111         bfs1(x,y);
112         if(t0==1e9+7)
113         {
114             printf("NOn");
115             continue;
116         }
117         bfs2();
118         if(t0>k)
119         {
120             printf("NOn");
121         }
122         else
123         {
124             printf("YESn%dn",t0);
125         }
126     }
127     return 0;
128 }

I wyh的物品

时间限制:C/C++ 5秒,其他语言10秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

wyh学长现在手里有n个物品,这n个物品的重量和价值都告诉你,然后现在让你从中选取k个,问你在所有可能选取的方案中,最大的单位价值为多少(单位价值为选取的k个物品的总价值和总重量的比值)

输入描述:

输入第一行一个整数T(1<=T<=10)
接下来有T组测试数据,对于每组测试数据,第一行输入两个数n和k(1<=k<=n<=100000)
接下来有n行,每行两个是a和b,代表这个物品的重量和价值

输出描述:

对于每组测试数据,输出对应答案,结果保留两位小数
示例1

输入

1
3 2
2 2
5 3
2 1

输出

0.75

说明

对于样例来说,我们选择第一个物品和第三个物品,达到最优目的

这道题目是一道0-1分数规划求最优值。

方法是一个二分搜索+贪心的题目。

出这道题目就是告诉大家二分不仅可以查找,还可以搜索一个更优值。

要使得单位重量的价值最大,则其最大不超过单个中最大的单位重量的价值,最小当然不小于0.

那么我们就这一在0--最大单位重量的价值中间找一个值ans,使得ans为满足题目条件的最大值。如果满足条件,则可以找更大的。设置一个条件。既二分搜索、

n个物品中找k个使得k个的价值和/质量和>=ans

为了使得ans尽可能的大,那么这里就要贪心选择。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define INF 1000010
 4 #define eps 1e-4
 5 double w[100005],v[100005];
 6 double y[100005];//v-x*w
 7 double max_ave;
 8 int n,k;
 9 bool get(double x)
10 {
11     int i;
12     double sum=0;
13     for(i=0;i<n;i++)
14     {
15         y[i]=v[i]-x*w[i];
16     }
17     sort(y,y+n);
18     for(i=0;i<k;i++)
19     {
20         sum+=y[n-i-1];
21     }
22     return sum>=0;
23 }
24 void bin()
25 {
26     double low,high,mid;
27     low=0.0;
28     high=INF;
29     for(int i=0;i<100;i++)
30     {
31         mid=(low+high)/2;
32         if(get(mid))
33             low=mid;
34         else high=mid;
35     }
36     printf("%.2lfn",high);
37 }
38 int main()
39 {
40     int i;
41     int tot;
42     cin>>tot;
43     while(tot--)
44     {
45         scanf("%d%d",&n,&k);
46         for(i=0;i<n;i++)
47         {
48             scanf("%lf%lf",&w[i],&v[i]);
49         }
50         bin();
51     }    
52     return 0;
53 }

J wyh的问题

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

我国现在能源消耗非常严重,现在政府有这样一个工作,每天早上都需要把一些路灯关掉,但是他们想让在关闭的过程中所消耗的能源是最少的,负责路灯关闭的工作人员以1m/s的速度进行行走,假设关闭路灯的时候不需要花费任何的时间,请你编写一个程序,计算在给定路灯位置和每个路灯的消耗能源的多少,求出当所有路灯关闭的时候所需要的最少能量

输入描述:

多组测试数据循环输入
每组测试数据第一行:N表示路灯的数量 (2<=N <=1000)
第二行:V表示开始关灯的路灯号码。 (1<=V<=N)
接下来的N行中,每行包含两个用空格隔开的整数D和W,用来描述每盏灯的参数
D表示该路灯到原点的距离 (用米为单位来表示),
W表示灯泡的功率,即每秒该灯泡所消耗的能量数。(0<=D<=1000,0<=W<=1000)
路灯按照顺序给出,起始位置的那盏灯不算消耗的电能里面

输出描述:

输出一个整数,即消耗能量之和的最小值。
示例1

输入

4
3
2 2
5 8
6 1
8 7

输出

56

说明

对于样例,我一开始在第三个路灯的位置,即在6位置
第1s的时候去5把第二盏灯关闭,消耗电能8
然后去第四盏灯,第四盏灯亮的时间是4s 所以消耗电能28
最后去关第一盏灯第一盏灯亮的时间是10s 所以消耗电能20
最后总和为8+28+20=56

关灯的人要么是去左边关灯,或者是去右边关灯,也即要关闭的下一个路灯要么是从已关闭路段的左端过去的,要么是从已关闭的路段的右端过去的,定义:

DP[i][j][0]表示i到j的路灯都已经关闭,人在路灯i的位置,此时已经消耗的最小电能

DP[i][j][1]表示i到j的路灯都已经关闭,人在路灯j的位置,此时已经消耗的最小电能

则状态转移式:

DP[i][j][0] = min(DP[i+1][j][0]+[i+1,j]路段以外未关闭路灯在人从i+1走的i期间消耗的电能,DP[i+1][j][1]+[i+1,j]路段以外未关闭路灯在人从j走到i期间消耗的电能)

DP[i][j][1] = min(DP[i][j-1][0]+[i,j-1]路段以外未关闭路灯在人从i走到j期间消耗的电能,DP[i][j-1][1]+[i,j-1]路段以外未关闭路灯在人从j-1走到j期间消耗的电能)

 1 #include <bits/stdc++.h>
 2 #define LEN 1001
 3 #define min(a,b) ((a<b)?(a):(b))
 4 
 5 int DP[LEN][LEN][2];
 6 int bw[LEN][LEN];
 7 int D[LEN];
 8 int W[LEN];
 9 
10 int main()
11 {
12     int N,V,tw=0;
13     int i,j,t;
14     while(scanf("%d %d",&N,&V)!=EOF)
15     {
16        tw = 0;
17        memset(bw, 0, sizeof(bw));
18        for(i=1; i<=N; ++i)
19        {
20          scanf("%d %d",&D[i],&W[i]); 
21          tw += W[i];
22        }
23        for(i=1; i<=N; ++i)
24        {
25           for(j=i; j<=N; ++j)
26           {
27               bw[i][j] = bw[i][j-1] + W[j];
28           }
29        }
30        
31        //初始化
32        for(i=V-1; i>0; --i)
33        {
34           DP[i][V][0] = DP[i+1][V][0]+(tw-bw[i+1][V])*(D[i+1]-D[i]);
35           DP[i][V][1] = DP[i][V][0] + (tw-bw[i][V])*(D[V]-D[i]);
36        } 
37        for(j=V+1; j<=N; ++j)
38        {
39           DP[V][j][1] = DP[V][j-1][1] + (tw-bw[V][j-1])*(D[j]-D[j-1]);
40           DP[V][j][0] = DP[V][j][1] + (tw-bw[V][j])*(D[j]-D[V]); 
41        }
42        
43        //DP
44        for(i=V-1; i>0; i--)
45        {
46           for(j=V+1; j<=N; ++j)
47           {
48              DP[i][j][0] = min(DP[i+1][j][0]+(tw-bw[i+1][j])*(D[i+1]-D[i]), 
49                                DP[i+1][j][1]+(tw-bw[i+1][j])*(D[j]-D[i]));
50              DP[i][j][1] = min(DP[i][j-1][0]+(tw-bw[i][j-1])*(D[j]-D[i]), 
51                                DP[i][j-1][1]+(tw-bw[i][j-1])*(D[j]-D[j-1]));
52           }
53        }
54        printf("%dn", min(DP[1][N][0], DP[1][N][1]));
55     }
56     return 0;
57 }

K wyh的数列

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

wyh学长特别喜欢斐波那契数列,F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n>=2)

一天他突发奇想,想求F(a^b)%c

输入描述:

输入第一行一个整数T(1<=T<=100),代表测试组数
接下来T行,每行三个数 a,b,c (a,b<=2^64) (1<c<1000)

输出描述:

输出第a^b项斐波那契数对c取余的结果
示例1

输入

3
1 1 2
2 3 1000
32122142412412142 124124124412124 123

输出

1
21
3
暴力打表会有循环节,比赛是想循环节的规律想到死,后来直接模拟求循环节。数据范围太大必须用 unsigned long long
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 unsigned long long arr[10000];
 4 
 5 unsigned long long int pm(unsigned long long int a, unsigned long long int b, unsigned long long int c) {
 6     unsigned long long int tmp = 1;
 7     a = a % c;
 8     while (b > 0) {
 9         if (b % 2 == 1)
10             tmp = (tmp * a) % c;
11         b /= 2;
12         a = (a * a) % c;
13     }
14     return tmp;
15 }
16 
17 int main(void) {
18     unsigned long long int t, a, b, c, cnt;
19     int  i;
20     scanf("%llu", &t);
21     while (t--) {
22         scanf("%llu %llu %llu", &a, &b, &c);
23         arr[0] = 0;
24         arr[1] = 1;
25         for (i = 2;; i++) {
26             arr[i] = (arr[i - 1] + arr[i - 2]) % c;
27             if (arr[i] == 1 && arr[i - 1] == 0) {
28                 cnt = i - 1;
29                 break;
30             }
31         }
32         unsigned long long int  dd = pm(a, b, cnt);
33         cout << arr[dd] << endl;
34     }
35     return 0;
36 }

 

L wyh的天鹅 

 

时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld 

题目描述

你们wyh学长小时候住在河边,因为周围的生态环境非常好,所以经常会有天鹅浮在湖面上,每只天鹅都长得不一样,它们偶尔排成一排,偶尔分散开,偶尔也会去其他河畔,wyh学长为了统计它们的个数,编了一个程序赋予它们一个“萌”值,但是这些天鹅很不听话,一会儿会从别的地方游过来一两只,一会儿又会在统计过程中游走一两只,现在请你帮他完成统计任务。

输入描述:

共有T(T<=10)组数据,每组数据第一行为两个数 N, M (N,M <= 500000),代表有N只天鹅和M次操作,接下来一行是N个数字,下面M行首先会输入一个字符串S,接着会有三类操作,如果S是“insert”,接着输入一个正整数a,代表插入一只“萌”值为a的天鹅,如果S是“delete”,接着输入一个正整数a,代表删除一只“萌”值为a的天鹅,如果S是“query”,接着输入一个正整数k,代表查询“萌”值第k大的天鹅。
萌值为[1,1000000000],并且保证一定存在第k大

输出描述:

对应每次询问,输出询问结果。
示例1

输入

1
5 4
6 4 2 9 1
query 2
insert 7
delete 6
query 2

输出

6
7
线段树维护数字个数,查询一下,比赛是全程卡bug,题解说是裸的平衡树
AC代码(线段树)
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int  MAX=1e6+10;
 4 int tree[4*MAX];
 5 int ans;
 6 void build(int l,int r,int rt){
 7     tree[rt]=0;
 8     if(l==r)
 9         return ;
10     int mid=(l+r)/2;
11     build(l,mid,2*rt);
12     build(mid+1, r, 2*rt+1);
13 }
14 
15 void update(int pos,int val,int l,int r,int rt){
16     if(l==r){
17         tree[rt]+=val;
18         return ;
19     }
20     int mid;
21     mid=(l+r)/2;
22     if(pos<=mid)
23         update(pos, val, l, mid, 2*rt);
24     else
25         update(pos, val, mid+1, r, 2*rt+1);
26     tree[rt]=tree[2*rt]+tree[2*rt+1];
27 }
28 
29 void query(int k,int l,int r,int rt){
30     if(l==r){
31         ans=l;
32         return ;
33     }
34     int mid;
35     mid=(l+r)/2;
36     if(tree[2*rt+1]>=k)
37         query(k, mid+1, r, 2*rt+1);
38     else
39         query(k-tree[2*rt+1], l, mid, 2*rt);
40 }
41 int main(){
42     int tot;
43     scanf("%d",&tot);
44     while(tot--){
45         build(0,MAX,1);
46         int num1,num2;
47         int x;
48         scanf("%d%d",&num1,&num2);
49         for(int i=1;i<=num1;i++){
50             scanf("%d",&x);
51             update(x, 1, 0, MAX, 1);
52         }
53         while(num2--){
54         string s;
55         cin>>s;
56         int n;
57         scanf("%d",&n);
58         if(s=="query"){
59             query(n, 0, MAX, 1);
60             cout<<ans<<endl;
61         }else if(s=="insert"){
62             update(n, 1, 0, MAX, 1);
63         }else {
64             update(n, -1, 0, MAX, 1);
65          }
66         }
67     }
68     return 0;
69 }

M wyh的数字

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld

题目描述

wyh学长十分钟爱数字‘7’,他想知道每一个数字中有多少个数字‘7’

输入描述:

输入第一行一个整数T(1<=T<=10)
接下来有T组测试数据,对于每组测试数据,输入一个整数n(1<=n<=10000000000)

输出描述:

对于每组测试数据,输出对应答案
示例1

输入

2
1234567
123456

输出

1
0
裸字符串查找
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int tt;
 5     cin>>tt;
 6     while(tt--){
 7         string s;
 8         cin>>s;
 9         int len;
10         len=(int )s.size();
11         int tot;
12         tot=0;
13         for(int i=0;i<len;i++){
14             if(s[i]-'0'==7){
15                 tot++;
16             }
17         }
18         cout<<tot<<endl;
19     }
20     return 0;
21 }

 



 

内容来源于网络如有侵权请私信删除
你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!