社区讨论

40pts求调

B4319[语言月赛 202504] 礼堂预约参与者 2已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mkla2zoo
此快照首次捕获于
2026/01/19 22:46
上个月
此快照最后确认于
2026/01/23 19:45
4 周前
查看原帖
求调喵,AI调了也调不出来
CPP
#include<bits/stdc++.h>
#define ll long long
#define db double
#define endl '\n'
#define int register int
#define AKIOI ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define AKNOI return 0
using namespace std;

ll day[]={0,31,28,31,30,31,30,31,31,30,31,30,31};

// 原活动结构体
struct activity{
    char typ;
    ll dat;
    char tim;
    ll bh;
}act[5005];

// 简化的活动信息结构体(用于mp存储)
struct activity2{
    char typ;
    ll bh;
    
    // 重载==运算符,用于判断两个activity2是否相等
    bool operator==(const activity2& other) const {
        return typ == other.typ && bh == other.bh;
    }
    
    // 重载<运算符,用于map的键排序(必须实现)
    bool operator<(const activity2& other) const {
        if (typ != other.typ) return typ < other.typ;
        return bh < other.bh;
    }
};

// 存储反向映射的键:日期+时间
struct TimeKey {
    ll dat;
    char tim;
};

// 原cmp函数(修正返回值逻辑,改为返回比较结果)
ll cmp(activity p,activity q){
    if(p.dat!=q.dat||p.tim!=q.tim) return 0; // 时间不同
    if(p.typ==q.typ) return 1;             // 类型相同
    if(p.typ=='O') return 2;               // p是O,优先级更高
    if(q.typ=='O') return 3;               // q是O,优先级更高
    if(p.typ=='C') return 2;               // p是C,优先级更高
    if(p.typ=='P') return 3;               // p是P,优先级更高
    return 0;
}

// 新增:闰年判断函数
bool isLeapYear(ll year) {
    // 规则1:能被4整除但不能被100整除 | 规则2:能被400整除
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

// 修复:日期+1函数(增加闰年判断)
ll day_more(ll data){
    ll y = data / 10000;   // 年
    ll m = data % 10000 / 100; // 月
    ll d = data % 100;     // 日
    
    d++; // 日期+1
    
    // 计算当月的天数(处理闰年2月)
    ll days_in_month = day[m];
    if (m == 2 && isLeapYear(y)) {
        days_in_month = 29; // 闰年2月29天
    }
    
    // 判断是否需要跨月
    if (d > days_in_month) {
        d = 1;
        m++;
        // 判断是否需要跨年
        if (m > 12) {
            y++;
            m = 1;
        }
    }
    
    // 重新组合日期
    return y * 10000 + m * 100 + d;
}

// 全局变量:原映射 + 反向映射
map<ll,map<char,activity2>> mp; // 正向:日期→时间→活动信息
map<activity2, TimeKey> reverse_mp; // 反向:活动信息→日期+时间

// 处理活动冲突的函数
void deal(activity now){
    // 检查当前日期+时间是否已有活动
    if(mp[now.dat][now.tim].typ == 0){ // 空值判断修正(原''改为0)
        // 正向映射赋值
        mp[now.dat][now.tim].typ = now.typ;
        mp[now.dat][now.tim].bh = now.bh;
        // 反向映射同步更新
        reverse_mp[{now.typ, now.bh}] = {now.dat, now.tim};
    }
    else{
        // 构造已存在的活动
        activity exist_act = {
            mp[now.dat][now.tim].typ,
            now.dat,
            now.tim,
            mp[now.dat][now.tim].bh
        };
        ll res = cmp(now, exist_act);
        
        if(res == 1 || res == 3){ // 类型相同 或 新活动优先级低
            // 新活动延后一天
            deal(activity{now.typ, day_more(now.dat), now.tim, now.bh});
        }
        else if(res == 2){ // 已存在的活动优先级低,延后已存在的活动
            // 先删除反向映射中旧的记录
            reverse_mp.erase({exist_act.typ, exist_act.bh});
            // 延后已存在的活动
            deal(activity{exist_act.typ, day_more(exist_act.dat), exist_act.tim, exist_act.bh});
            // 更新当前位置为新活动
            mp[now.dat][now.tim].typ = now.typ;
            mp[now.dat][now.tim].bh = now.bh;
            reverse_mp[{now.typ, now.bh}] = {now.dat, now.tim};
        }
    }
}

ll n;
signed main(){
    AKIOI;
    cin >> n;
    for(int i=1;i<=n;i++){
        cin >> act[i].typ >> act[i].dat >> act[i].tim;
        act[i].bh = i; // 编号改为i,避免重复(原1会导致所有活动编号相同)
        deal(act[i]); // 处理每个活动
    }
    for(int i=1;i<=n;i++){
    	cout<<reverse_mp[activity2{act[i].typ,i}].dat<<endl;
	}
    AKNOI;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...