【深入浅出程序设计竞赛】:Bovine Bones G、开灯

158 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 30 天,点击查看活动详情

[USACO08OCT]Bovine Bones G

题面翻译

贝茜喜欢玩棋盘游戏和角色扮演游戏,所以她说服了约翰开车带她去小商店.在那里她买了三个骰子。这三个不同的骰子的面数分别为 s1,s2,s3s_1,s_2,s_3

对于一个有 SS 个面的骰子每个面上的数字是 1,2,3,,S1,2,3,\ldots,S。每个面(上的数字)出现的概率均等。贝茜希望找出在所有“三个面上的数字的和”中,哪个和的值出现的概率最大。

现在给出每个骰子的面数,需要求出哪个所有“三个面上的数字的和”出现得最频繁。如果有很多个和出现的概率相同,那么只需要输出最小的那个。

输入格式

* Line 1: Three space-separated integers: S1, S2, and S3

输出格式

* Line 1: The smallest integer sum that appears most frequently when the dice are rolled in every possible combination.

样例 #1

样例输入 #1

3 2 3

样例输出 #1

5

提示

数据范围: 2s1202\le s_1\leq 202s2202 \leq s_2\leq 202s3402 \leq s_3\leq 40

1 1 1 -> 3  
1 2 1 -> 4  
2 1 1 -> 4  
2 2 1 -> 5  
3 1 1 -> 5  
3 2 1 -> 6 
1 1 2 -> 4  
1 2 2 -> 5  
2 1 2 -> 5  
2 2 2 -> 6  
3 1 2 -> 6  
3 2 2 -> 7 
1 1 3 -> 5  
1 2 3 -> 6  
2 1 3 -> 6  
2 2 3 -> 7  
3 1 3 -> 7  
3 2 3 -> 8

Both 5 and 6 appear most frequently (five times each), so 5 is the answer.

代码

#include<bits/stdc++.h>
using namespace std;

int flag[100001];
int s1,s2,s3;

int main() {
    cin >> s1 >> s2 >> s3;
    for(int i=1; i<=s1; i++)
        for(int j=1; j<=s2; j++)
            for(int z=1; z<=s3; z++)
                flag[i+j+z]++;
                
    int max=INT_MIN, res=0;
    
    for(int i=1;i<=s1*s2*s3;i++) {
        if(flag[i] > max) {
            max = flag[i];
            res = i;
        }
    }
    cout << res;
    return 0;
}

开灯

题目描述

在一条无限长的路上,有一排无限长的路灯,编号为 1,2,3,4,1,2,3,4,\dots

每一盏灯只有两种可能的状态,开或者关。如果按一下某一盏灯的开关,那么这盏灯的状态将发生改变。如果原来是开,将变成关。如果原来是关,将变成开。

在刚开始的时候,所有的灯都是关的。小明每次可以进行如下的操作:

指定两个数,a,ta,taa 为实数,tt 为正整数)。将编号为 a,2×a,3×a,,t×a\lfloor a\rfloor,\lfloor 2 \times a\rfloor,\lfloor3 \times a\rfloor,\dots,\lfloor t \times a\rfloor 的灯的开关各按一次。其中 k\lfloor k \rfloor 表示实数 kk 的整数部分。

在小明进行了 nn 次操作后,小明突然发现,这个时候只有一盏灯是开的,小明很想知道这盏灯的编号,可是这盏灯离小明太远了,小明看不清编号是多少。

幸好,小明还记得之前的 nn 次操作。于是小明找到了你,你能帮他计算出这盏开着的灯的编号吗?

输入格式

第一行一个正整数 nn,表示 nn 次操作。

接下来有 nn 行,每行两个数,ai,tia_i,t_i。其中 aia_i 是实数,小数点后一定有 66 位,tit_i 是正整数。

输出格式

仅一个正整数,那盏开着的灯的编号。

样例 #1

样例输入 #1

3
1.618034 13
2.618034 7
1.000000 21

样例输出 #1

20

提示

T=i=1n=t1+t2+t3++tnT=\sum \limits_{i=1}^n = t_1+t_2+t_3+\dots+t_n

对于 30%30\% 的数据,满足 T1000T \le 1000

对于 80%80\% 的数据,满足 T200000T \le 200000

对于 100%100\% 的数据,满足 T2000000T \le 2000000

对于 100%100\% 的数据,满足 n5000,1ai<1000,1tiTn \le 5000,1 \le a_i<1000,1 \le t_i \le T

数据保证,在经过 nn 次操作后,有且只有一盏灯是开的,不必判错。而且对于所有的 ii 来说,ti×ait_i\times a_i 的最大值不超过 20000002000000

代码

#include<bits/stdc++.h>
using namespace std;
int l[2000001];  // 0 是 关  1 是 开 
double a, t;
int main() {
    int n;
    cin >> n;
    for(int i = 1; i<=n; i++) {
        cin >> a >> t;
        for(double j = 1; j<=t; ++j) {
            if(l[int(j*a)] == 0) {
                l[int(j*a)] = 1;
            }else {
                l[int(j*a)] = 0;
            }
        } 
    }
    int ans = 1;
    while(1) {
        if(l[ans] == 1) {
            cout << ans;
            break; 
        }
        ans++;
    }
    return 0;
}