2024.08.25百度(难度还行)

1. 时钟指针

小A的寝室里放着一个时钟。时钟有时针,分针,秒针三种指针。
在某些时刻,时钟会记录下当前时间,格式为 hh:mm:ss 。
时钟上看不出日期,每天零点,三根指针都会归零。
现在小A得到了一系列被记录的时间,且这些时间是按照先后顺序被记录的。
小A想让你算算,每两个时间点之间,秒针至少转了多少圈。

读取解析以及计算
int trans(string &a){//将字符串转化为秒
    int idx = 0;
    int hour = 0;
    while(a[idx]!=':'){
        hour = hour*10 + (a[idx]-'0');
        idx++;
    }
    int minute = 0;
    while(a[idx]!=':'){
        minute = minute*10 + (a[idx]-'0');
        idx++;
    }
    int second = 0;
    while(idx!=a.size()){
        second = second*10 + (a[idx]-'0');
        idx++;
    }
    second += (hour*60+minute)*60;
    return second;
}

double cal(string&a,string&b){
    int num1 = trans(a); int num2 = trans(b);
    if(num1>=num2) num2+=(24*60*60);
    return (double)(num2-num1)/60;
}

int main() {
    int n;
    cin>>n;
    string cur;
    cin>>cur;
    for(int i=0;i<n-1;i++){
        if(i!=0) cout<<" ";
        string next;
        cin>>next;
        cout<<cal(cur,next);
        cur = next;
    }
    return 0;
}

2. 数学题

牛牛最近在做比大小的小学数学题目,每个题目可以表示为:a op b ( ) b op a 。
a,b 分别表示两个正整数。op 表示一个数学意义上的运算符(包括加 + 减 - 乘 * 除 / 和乘方 ^ 运算)。
( ) 表示你需要填写的答案,是符号 =, < , > 其中的一个。

简单模拟
char check(double a, double b) {
    if (a > b) return '>';
    if (a < b) return '<';
    return '=';
}

int main() {
    int n;
    cin >> n;

    vector<char> res;

    for (int i = 0; i < n; i++) {
        double a, b;
        string op;
        cin >> a >> b >> op;

        if (op == "+" || op == "*") {
            res.push_back('=');
        } else if (op == "-") {
            res.push_back(check(a - b, b - a));
        } else if (op == "/") {
            res.push_back(check(a / b, b / a));
        } else if (op == "^") {
            double log_a = log(a);
            double log_b = log(b);
            if (b * log_a > a * log_b) res.push_back('>');
            else if (b * log_a < a * log_b) res.push_back('<');
            else res.push_back('=');
        }
    }

    for (char c : res) {
        cout << c << endl;
    }

    return 0;
}

3. 流言终结者

在一个小镇住着n个人,其中有m对朋友关系。朋友关系是相互的,即A是B的朋友也意味着B是A的朋友。
这n个人分为两类:第一种人听到一个流言之后,会把它说给所有没有听过这个流言的朋友听。
第二种人听到一个流言之后,不会把它说给任何一个朋友听。现在有q次事件发生,每次事件形如"有一个人u听说了某个流言",每次事件独立。
请问对于每一次事件,有多少人最终会听到这个流言?

需要先预处理,因为查询量很大,这里采用并查集序号的方式
给不同连通域标号,同时记录对应序号连通域大小,需要注意的是第二类朋友相当于边界和公共区域

int main() {
    int n,m,q;
    cin>>n>>m>>q;
    vector<vector<int>> graph(n+1);
    for(int i=0;i<m;i++){
        int from; int to;
        cin>>from>>to;
        graph[from].push_back(to);
        graph[to].push_back(from);
    }
    vector<int> kind(n+1);
    for(int i=1;i<=n;i++)
        cin>>kind[i];

    int idx = 0;
    vector<int> flag(n+1,-1);//连通域序号
    unordered_map<int,int> mp;
    function<void(int,int)> dfs = [&](int u,int id)->void{
        flag[u] = id;
        mp[id]++;//对应连通域数目增加
        if(kind[u]==2) return;//禁止拓展
        for(auto v:graph[u]){
            if(kind[v]==2&&flag[v]!=id) dfs(v,id);//将该公共区域转化成私有区域
            if(kind[v]==1&&flag[v]==-1) dfs(v,id);//拓展连通域
        }
    };
    //第二种人相当于连通域的公共区域以及边界
    for(int i=1;i<=n;i++){
        if(kind[i]==2) continue;//第二种人只会有一个人听到流言
        if(flag[i]==-1) dfs(i,idx++);
    }

    for(int i=0;i<q;i++){
        if(i!=0) cout<<" ";
        int query;
        cin>>query;
        if(kind[query]==2) cout<<1;
        else cout<<mp[flag[query]];
    }
    return 0;
}
posted @ 2024-09-10 14:45  失控D大白兔  阅读(5)  评论(0编辑  收藏  举报