1. 程式人生 > >Codeforces 417 Div.2

Codeforces 417 Div.2

put 2個 printf inpu out 我們 可能 pac ima

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 2
0010
0100
output
5
input
3 4
001000
000010
000010
output
12
input
4 3
01110
01110
01110
01110
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 11
2 3 5
output
2 11
input
4 100
1 2 5 6
output
4 54
input
1 7
7
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 }

 

Codeforces 417 Div.2