Codeforces 417 Div.2

A.给你1、2、3、4道路上的车和行人当前的红绿灯状况(绿灯:1、红灯:0)

问:各个道路上的汽车是否会撞到其他道路上的行人

记录会出现汽车的道路编号,判断此时该道路上是否有行人即可

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 int a[5][5];
 5 int vis[5];
 6 int b[4]={1,2,3,4};
 7 int main()
 8 {
 9     for(int i=1; i<=4; i++)
10     {
11         for(int j=0; j<4; j++)
12             scanf("%d",&a[i][j]);
13         for(int j=0; j<3; j++)
14             if(a[i][j]==1)
15             {
16                 vis[i]=1;   //标记会出现车辆的道路
17                 vis[b[(2-j+i)%4]]=1; //同上
18             }
19     }
20     int flag=0;
21     for(int i=1; i<=4; i++)
22         if(a[i][3]==1 && vis[i]==1)  //若有行人,则YES
23             flag=1;
24     if(flag) cout<<"YES"<<endl;
25     else cout<<"NO"<<endl;
26     return 0;
27 }

B.给你n层楼,每层有m+2个,左右分别为0,代表楼梯,剩下m个房间1表示有人,0则没有人,走一个耗时1

开始位置位于左下角,问:需要的最少的时间是多少

Examples

input

2 200100100

output

5

input

3 4001000000010000010

output

12

input

4 301110011100111001110

output

18

先记录每层的有人房间的最左的位置,最右位置。

用dp[i][0]表示走到i层的左楼梯的最少步数,dp[i][1]表示走到i层的右楼梯的最少步数,递推关系式,就能推出来了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 char s[20][105];
 5 int dp[20][2];
 6 int l[20],r[20];
 7
 8 int main()
 9 {
10     int n,m;
11     scanf("%d%d",&n,&m);
12     for(int i=n; i>=1; i--)
13     {
14         scanf("%s",s[i]);
15         int flag=0;
16         for(int j=0; j<m+2; j++)
17             if(s[i][j]==‘1‘) r[i]=j,flag=1;
18         for(int j=m+1; j>=0; j--)
19             if(s[i][j]==‘1‘) l[i]=j,flag=1;
20         if(!flag) r[i]=l[i]=0;  //记录下最左最右房间位置,若该层没有,记为0
21     }
22     dp[1][0]=0,dp[1][1]=m+1;  //第一层dp结果是确定的
23     for(int i=2; i<=n; i++)
24     {
25         if(l[i-1])  //前一层有房间的话
26         {
27             dp[i][0]=min(dp[i-1][0]+r[i-1]*2+1,dp[i-1][1]+m+2);  //+1是要向上一层
28             dp[i][1]=min(dp[i-1][0]+m+2,dp[i-1][1]+(m+1-l[i-1])*2+1);
29         }
30         else
31         {
32             dp[i][0]=min(dp[i-1][0]+1,dp[i-1][1]+m+2);  //该层没人,直接向上走
33             dp[i][1]=min(dp[i-1][0]+m+2,dp[i-1][1]+1);
34         }
35     }
36     int ans,flag=0;
37     for(int i=n; i>=1; i--)
38         if(l[i])  //最后再判断最后有人的一层的最小情况
39         {
40             ans=min(dp[i][0]+r[i],dp[i][1]+m+1-l[i]);
41             flag=1;
42             break;
43         }
44     printf("%d",flag ? ans : 0);  //可能出现全为0的情况
45     return 0;
46 }

C.给你n件物品的价格,和s的预算,问你最多能买几件物品,若最大物品数相同,则要使花费最少

sumPrice=cnt件物品的价格之和+cnt件物品的下标和×件数

Examples

input

3 112 3 5

output

2 11

input

4 1001 2 5 6

output

4 54

input

1 77

output

0 0

我们这样考虑:把cnt件的下标和×cnt,分配到每件上,那么其实每件的价格+=cnt×自己的下标,那么对于某一个cnt来说,不妨把所有的物品价格都+=cnt×自己下标,再sort以下,取前cnt件,那么一定是cnt件情况下,花费最少的。

然后呢,n~1e5,s~1e9,暴力说到底,勉强能过,因为cnt×下标和,达到了cnt^3,所以件数不会超过1e3;

不难想到,价格总和 正相关于 cnt,所以二分,查找即可

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4
 5 const int N=1e5+5;
 6 int n,s,a[N];
 7 LL b[N];
 8
 9 LL check(int m)
10 {
11     for(int i=1; i<=n; i++)
12         b[i]=a[i]+1LL*i*m;
13     sort(b+1,b+n+1);
14     LL ret=0;
15     for(int i=1; i<=m; i++)
16         ret+=b[i];
17     return ret;
18 }
19
20 int main()
21 {
22     scanf("%d%d",&n,&s);
23     for(int i=1; i<=n; i++)
24         scanf("%d",&a[i]);
25     int l=0,r=n;
26     while(l<=r)
27     {
28         int m=(l+r)/2;
29         if(check(m)<=1LL*s) l=m+1;
30         else r=m-1;
31     }
32     printf("%d %lld",l-1,check(l-1));
33     return 0;
34 }
 
时间: 2024-08-15 23:17:52

Codeforces 417 Div.2的相关文章

Codeforces Round #417 (Div. 2) A. Sagheer and Crossroads 模拟 枚举

Codeforces Round #417 (Div. 2) A. Sagheer and Crossroads 模拟  枚举 题意 一个红绿灯 按逆时针方向一次给出各个路口的左转,直行,右转,以及行人车道让你判断,汽车是否有可能撞到行人 注意 当前车道的左转有可能撞到别的车道的行人的 题解 一大堆特判 1 #include <cstdio> 2 #include <cmath> 3 #include <cstdlib> 4 #include <cstring&g

Codeforces Round #417 (Div. 2) C. Sagheer and Nubian Market 二分答案 +排序

Codeforces Round #417 (Div. 2) C. Sagheer and Nubian Market 二分答案 +排序 题意 有 a[ i ] 个数 要求选最多的数 使其和不超过 S ,且在此情况下,和最小选最多数情况下 和最小 且 每个数有加成 如果选了 k个数 那么加成后 就是 a[ i ] + k*i ; 题解 二分mid 表示选了个数 加成一下,将加成以后结果排序一下 , 若前 mid数 和大于 s 则此方案不可行 PS 要用 long long ..... 还有 co

Codeforces Round #417 (Div. 2) E. Sagheer and Apple Tree(树上Nim)

题目链接:Codeforces Round #417 (Div. 2) E. Sagheer and Apple Tree 题意: 给你一棵树,每个节点有a[i]个苹果,有两个人要在这个树上玩游戏. 两个人轮流操作,谁不能操作谁就输了. 这个树有一个特性:叶子到根的距离的奇偶性相同. 每次操作可以选一个节点i,和一个数x,x小于当前节点i的苹果数. 对于节点i,如果是叶子节点,就将这x个苹果吃掉. 如果是非叶子节点,就将这x个苹果移向节点i的任意儿子节点. 现在第二个操作的人要交换两个节点的苹果

Codeforces Round #417 (Div. 2) B. Sagheer, the Hausmeister(DP)

题目链接:Codeforces Round #417 (Div. 2) B. Sagheer, the Hausmeister 题意: 有n层楼,每层有m个房间,每层的两边是楼梯. 现在有一个人站在左下角,这个人必须将这一层的灯关闭后才能去另外一层. 每移动一次需要1分钟,问关闭所有灯需要多少时间. 题解: 考虑DP[i][j]表示当前已经关闭了第i层全部的灯,j=0时表示在这一层的最左边,j=1时表示在这一层的最右边. 然后推上去就行了.最后讨论一下特殊情况. 1 #include<bits/

Codeforces #258 Div.2 E Devu and Flowers

大致题意: 从n个盒子里面取出s多花,每个盒子里面的花都相同,并且每个盒子里面花的多数为f[i],求取法总数. 解题思路: 我们知道如果n个盒子里面花的数量无限,那么取法总数为:C(s+n-1, n-1) = C(s+n-1, s). 可以将问题抽象成:x1+x2+...+xn = s, 其中0<=xi <= f[i],求满足条件的解的个数. 两种方法可以解决这个问题: 方法一:这个问题的解可以等价于:mul = (1+x+x^2+...+x^f[1])*(1+x+x^2+...+x^f[2]

Codeforces #259 Div.2

A. Little Pony and Crystal Mine 模拟题. 用矩阵直接构造或者直接根据关系输出 B. Little Pony and Sort by Shift 模拟题. 通过提供的操作得到的序列只能是两段递增或者整个序列递增. 那么可以求得第一段递增序列长度为0-p 如果整个序列是递增,即 p= n-1 那么操作次数就是0. 否则,假设是两段递增,把原始的序列恢复出来,设当前序列是AB,那么A就是0-p BA = (A'B')', '表示对序列进行翻转, 如果BA是有序的,那么需

Codeforces #250 (Div. 2) C.The Child and Toy

之前一直想着建图...遍历 可是推例子都不正确 后来看数据好像看出了点规律 就抱着试一试的心态水了一下 就....过了..... 后来想想我的思路还是对的 先抽象当前仅仅有两个点相连 想要拆分耗费最小,肯定拆相应权值较小的 在这个基础上考虑问题就能够了 代码例如以下: #include <cstdio> #include <iostream> #include <algorithm> #define MAXN 10010 #define ll long long usi

Codeforces #256 Div.2

B. Suffix Structure 1. 先判断s去掉一些元素是否能构成t,如果可以就是automaton 判断的方法也很简单,two pointer,相同元素同时++,不相同s的指针++,如果t能全找到,那么s能够去掉元素构成t. bool f(string s, string t) { int i = 0, j = 0; while (i < s.size() && j < t.size()) { if (s[i] == t[j]) { i++; j++; } else

(博弈\sg) Codeforces Round #417 (Div. 2) E Sagheer and Apple Tree

Sagheer is playing a game with his best friend Soliman. He brought a tree with n nodes numbered from 1 to n and rooted at node 1. The i-th node has ai apples. This tree has a special property: the lengths of all paths from the root to any leaf have t