大模拟挑战

1.儒略日

这貌似不像是模拟,倒像小学数学题?

代码
#define sandom signed
#include <bits/stdc++.h>
#define re register int
#define int long long 
using namespace std;
inline int read() { int x = 0, f = 0; char c = getchar(); while (!isdigit(c)) f = c == '-', c = getchar(); while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48), c = getchar(); return f ? -x : x; }

int sum[3][13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, //平年
                  0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, //闰年
                  0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 21, 30, 31};//特殊的年
int tot[410];
int day = 1, month, year = -4713, tim, n;
inline void calc(int op)//计算一年中的时间
{
    for (re i = 1; i <= 12; i++)//找到第一个不完整的月
        if (tim < sum[op][i]) { month = i; break; }
    tim -= sum[op][month - 1], day += tim;
}
inline void work(int op)
{
    if (tim >= sum[op][12]) year++, tim -= sum[op][12];
    else if (!month) calc(op);
}
inline void solve(int t, int Lim)
{
    int leap_year = min(tim / tot[t], Lim);
    year += leap_year * t;
    tim -= leap_year * tot[t];
}
inline bool check(int x) { return (x % 4 == 0 && x % 100 != 0) || (x % 400 == 0); }
inline void BC() { printf("%lld %lld %lld BC\n", day, month, -year); }
inline void CE() { printf("%lld %lld %lld\n", day, month, year); }

sandom main()
{
    n = read();
    for (re t = 0; t <= 2; t++) for (re i = 1; i <= 12; i++) sum[t][i] += sum[t][i - 1];
    for (re i = 1; i <= 400; i++) tot[i] = tot[i - 1] + sum[check(i)][12];
    while (n--)
    {
        tim = read(); day = 1, month = 0, year = -4713;
        /*公元前*/
        solve(4, 1178);
        work(1); if (year) work(0), work(0), work(0);//闰平平平
        if (month) { BC(); continue; }
        /*1~1582*/
        year = 1; solve(4, 395);//每四年为一轮
        work(0); if (year < 1582) work(0), work(0), work(1);//平平平闰
        if (month) { CE(); continue; }
        /*1582~1583*/
        work(2); if (month == 10 && day > 4) day += 10;
        if (month) { CE(); continue; }
        /*1583~1600*/
        solve(4, 4);
        work(0), work(1); if (year < 1600) work(0), work(0);//平闰平平
        if (month) { CE(); continue; }
        /*1601~新时代*/
        solve(400, 1e18), solve(100, 3), solve(4, 24);//按轮换缩小范围
        work(0), work(0), work(0), work(check(year));//平平平闰(但是注意百年要判为平年)
        if (month) { CE(); continue; }
    }
    return 0;
}

2.预处理器

省选题,但\(filled \ with \ water\),大模拟才五六十行。

代码
#define sandom signed
#include <bits/stdc++.h>
#define re register int 
using namespace std;

string x, y;
map <string, string> def;
map <string, bool> vs;
inline bool judge(char c) { return isdigit(c) || isalpha(c) || c == '_'; }
inline string solve(string x);
inline string get1(int n, string x, int &i, int &j)//字符
{
    while (j < n && judge(x[j])) j++;
    string a = x.substr(i, j - i), b;
    while ((vs.find(a) == vs.end() || vs[a] == 0) && def.find(a) != def.end())
    {
        vs[b = a] = 1;
        a = def[a]; a = solve(a);
        vs.erase(b);
    }
    i = j; return a;
}
inline string get2(int n, string x, int &i, int &j)//非字符
{   
    while (j < n && !judge(x[j])) j++;
    string a = x.substr(i, j - i); 
    i = j; return a;
}
inline string solve(string x)//递归处理
{
    int i = 0, j = 0, n = x.length(); string y;
    while (i < n) y += get1(n, x, i, j), y += get2(n, x, i, j);
    return y;
}

sandom main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T; cin >> T; getline(cin, x);
    while (T--)
    {
        getline(cin, x); y.erase();
        if (x[0] == '#')
        {
            int pos1 = x.find(' ', 0) + 1, pos2 = x.find(' ', pos1 + 1) + 1;
            string a = x.substr(pos1, pos2 - pos1 - 1), b = x.substr(pos2);
            if (x[1] == 'd') def[a] = b;
            else def.erase(a);
        }
        else y = solve(x);
        cout << y << endl;
    }
    return 0;
}

3.猪国杀

好吧,我被恶心到了。调试过程中有趣的事故(故事):
1.反猪死了,但是还在出牌(死而复生);
2.忠猪救了另一个忠猪,但是没有救主猪(狼心狗肺);
3.忠猪使用了万箭齐发,但是没有使用无懈可击救主猪(内奸);
4.主猪杀死了忠猪,但继续使用猪葛连弩疯狂扫射(89*潮);
5.忠猪与主猪决斗(革命军);
6.所有人都不想帮助忠猪(底层苦难者);
7.濒死,哎还没死(反复横跳);
8.一直要吃桃(吃pea);
9.跳身份之后,主猪没有重新认识它(这就是刻板印象吗)。

代码
#define sandom signed
#include <bits/stdc++.h>
#define re register int 
#define rep(i, a, b) for (re (i) = (a); (i) <= (b); ++(i))
#define dwn(i, a, b) for (re (i) = (a); (i) >= (b); --(i))
#define aut(i, x) for (auto (i) = (x.card.begin()); i < (x.card.end()); ++(i))
using namespace std; typedef vector<char>::iterator it;

int n, m, ans;
queue <char> CARD;//牌堆
struct pig
{
    string id;//身份
    vector <char> card;//手牌
    int pre, nxt, pos;//前后猪
    int life;//血量
    bool weapon;//装备武器
    bool loyalty;//忠臣
    bool rebel;//反贼
    bool wl_rebel;//类反猪
    bool dead;//死亡
}; pig role[12];
inline int win()//判定游戏结果
{
    if (role[1].dead) return -1;//主猪阵亡
    else rep(i, 2, n) if (role[i].id == "FP" && !role[i].dead) return 0;//还没结束
    return 1;//反猪全死
}
void Game_over()//结束游戏
{
    int flag = win();
    if (flag == -1) puts("FP");//反猪胜利
    else puts("MP");//主猪胜利
    for (re i = 1; i <= n; i++)
    {
        if (role[i].dead) puts("DEAD");
        else { aut(pos, role[i]) putchar(*pos), putchar(' '); putchar('\n'); }
    }
    exit(0);
}
void get_card(int x, int cnt)//pig x摸cnt张牌
{
    rep(i, 1, cnt)
    {
        role[x].card.push_back(CARD.front());
        if (CARD.size() > 1) CARD.pop();
    }
}

#define __ if (role[y].nxt == x.pos) return 0;//没找到
int find_enemy(pig x, bool op)//第一个想要攻击的猪
{
    int y = x.nxt;
    if (x.id == "MP") while (!role[y].rebel && !role[y].wl_rebel) { __ y = role[y].nxt; }
    if (x.id == "ZP") while (!role[y].rebel) { __ y = role[y].nxt; }
    if (x.id == "FP")
    {
        if (x.nxt == 1 || op) return 1;//下一个就是主猪或者是决斗牌
        else while (!role[y].loyalty) { __ y = role[y].nxt; }
    }
    return y;
}
int find_hostile(pig x, pig z)//x后面第一个与z敌对的猪
{
    int y = x.pos;
    if (z.loyalty) while (role[y].id != "FP") { __ y = role[y].nxt; }
    else if (z.rebel) while (role[y].id != "MP" && role[y].id != "ZP") { __ y = role[y].nxt; }
    else y = 0;
    return y;
}
int find_alliance(pig x, pig z)//x后面第一个与z同盟的猪
{
    int y = x.pos;
    if (z.loyalty) while (role[y].id != "MP" && role[y].id != "ZP") { __ y = role[y].nxt; }
    else if (z.rebel) while (role[y].id != "FP") { __ y = role[y].nxt; }
    else y = 0;
    return y;
}

void Protect(pig &x, pig &y)//x对y献殷勤
{
    if (y.loyalty) x.loyalty = 1, x.wl_rebel = 0;
    if (y.rebel) x.rebel = 1, x.wl_rebel = 0;
}
void Attack(pig &x, pig &y)//x对y表敌意
{
    if (y.rebel) x.loyalty = 1, x.wl_rebel = 0;
    if (y.loyalty) x.rebel = 1, x.wl_rebel = 0;
}
void Peach(pig &x)//需要打出一张桃
{
    aut(pos, x) if (*pos == 'P') { x.card.erase(pos), x.life++; return; }
}
void dying(pig &x, pig &y)//濒死
{
    x.life--;   rep(i, x.life, 0) Peach(x);
    if (x.life <= 0)//已经死了
    {
        x.dead = 1;
        role[x.pre].nxt = x.nxt;
        role[x.nxt].pre = x.pre;
        if (win()) Game_over();
        if (x.id == "FP") get_card(y.pos, 3);//摸牌奖励
        if (x.id == "ZP" && y.pos == 1) role[1].card.clear(), role[1].weapon = 0;//弃牌惩罚
    }
}
inline bool Kill(pig &x, pig &y)//需要打出一张杀
{
    aut(pos, x) if (*pos == 'K') { x.card.erase(pos); return false; }
    dying(x, y); return true;
}
inline bool Dodge(pig &x, pig &y)//需要打出一张闪
{
    aut(pos, x) if (*pos == 'D') { x.card.erase(pos); return false; }
    dying(x, y); return true;
}
inline bool Offset(pig &x)//需要打出一张无懈可击
{
    aut(pos, x) if (*pos == 'J') { x.card.erase(pos); return true; }
    return false;
}
bool will_be_attacked(pig &x, pig &y, bool op);
bool will_be_protected(pig &x, pig &y)//x将要给y献殷勤
{
    Protect(x, y); 
    int lim = find_hostile(x, y), z = lim;
    do
    {
        if (z && Offset(role[z]) && will_be_attacked(role[z], y, 1)) return false;//可以阻止
        z = find_hostile(role[role[z].nxt], y);
    } while (z != lim && z);
    return true;
}
bool will_be_attacked(pig &x, pig &y, bool op)//x将要给y表敌意
{
    if (op) Attack(x, y);
    int lim = find_alliance(x, y), z = lim;
    do
    {
        if (z && Offset(role[z]) && will_be_protected(role[z], y)) return false;//可以阻止
        z = find_alliance(role[role[z].nxt], y);
    } while (z != lim && z);
    return true;
}

int Peach_launch(pig &x, it pos)//桃
{
    if (x.life < 4) { x.life++, x.card.erase(pos); return 1;}
    return 0;
}
int Kill_launch(pig &x, it pos)//杀
{
    int y = find_enemy(x, 0);
    if (y && x.nxt == y) x.card.erase(pos), Attack(x, role[y]), Dodge(role[y], x);
    return y && x.nxt == y;//只能打下一个
}
void Fight_Response(pig &x, pig &y)//决斗__
{
    if (x.id == "ZP" && y.id == "MP") { dying(x, y); return; }//忠猪不会反抗主猪
    while (1)//不遗余力地杀
    {
        if (Kill(x, y)) break;
        if (Kill(y, x)) break;
    }
}
int Fight(pig &x, it pos)//决斗
{
    int y = find_enemy(x, 1);
    if (y) x.card.erase(pos);
    if (y && will_be_attacked(x, role[y], 1)) Fight_Response(role[y], x);
    return y;
}
void Invade(pig &x, it pos)//南蛮入侵
{
    x.card.erase(pos); int y = x.nxt;
    while (y != x.pos)
    {
        if (will_be_attacked(x, role[y], 0) && Kill(role[y], x) && y == 1 && !x.loyalty && !x.rebel) x.wl_rebel = 1;
        y = role[y].nxt;
    }
}
void Arrows(pig &x, it pos)//万箭齐发
{
    x.card.erase(pos); int y = x.nxt;
    while (y != x.pos)
    {
        if (will_be_attacked(x, role[y], 0) && Dodge(role[y], x) && y == 1 && !x.loyalty && !x.rebel) x.wl_rebel = 1;
        y = role[y].nxt;
    }
}
void Crossbow(pig &x, it pos)//诸葛连弩
{
    x.card.erase(pos), x.weapon = 1;
}

void putout_card(int x)//出牌阶段
{
    bool op = 1;
    game: if (role[x].dead) return;
    aut(pos, role[x])
    {
        switch (*pos)
        {
            case 'P': if (Peach_launch(role[x], pos)) goto game; break;
            case 'K': if ((role[x].weapon || op) && (Kill_launch(role[x], pos))) { op = 0; goto game; } break;
            case 'F': if (Fight(role[x], pos)) goto game; break;
            case 'N': Invade(role[x], pos); goto game; break;
            case 'W': Arrows(role[x], pos); goto game; break;
            case 'Z': Crossbow(role[x], pos); goto game; break;
            default: break;
        }
    }
}

sandom main()
{
    cin >> n >> m; char s;
    rep(i, 1, n)//个人信息
    {
        cin >> role[i].id; role[i].life = 4;
        rep(j, 1, 4) cin >> s, role[i].card.push_back(s);
    }
    rep(i, 1, n) role[i].pos = i, role[i].pre = i - 1, role[i].nxt = i + 1;
    role[1].pre = n, role[n].nxt = 1;  role[1].loyalty = 1;
    rep(i, 1, m) cin >> s, CARD.push(s);//牌堆
    int now = 1;
    while (1)
    {
        get_card(now, 2), putout_card(now);
        now = role[now].nxt;
    }
    return 0;
}

4.……

代码
posted @ 2022-10-05 07:04  sandom  阅读(76)  评论(0编辑  收藏  举报