【题解】[SCOI2011] 飞镖

模拟题

红靶子的我们先不考虑。

如果是 {1,2,2} , {2,2,3} 这种只涉及两种倍数的话,我们想到不定方程:

ax+by =c 的通解形式(a,b,c 为常数),从而探讨 x,y 在规定取值内是否有解。

探讨 {1,2,3} 的情况。

这个时候不难发现 x ∈ [ 1 , 6 k ] x\in [1,6k] x[1,6k] 是有解的。

如果你暴力每种情况枚举的话会比较麻烦。

我们可以递归求解:(当然这是个笨方法)

对于轮数为 1 的情况相对较少,直接求解。

对于轮数等于 2 的情况,有几种情形:

第一种,有一个为 M 的靶

第二种,有一个为 2M 的靶

第三种,没有红心靶

组合形式为

{2,2}, {1,2} , {2,3}

如果之前有过 2M 的靶,还可以是:

{3,3} , {1,3}

对于轮数等于 3 的情况,有几种情形:

第一种,有一个为 M 的靶

第二种,有一个为 2M 的靶

第三种,没有红心靶

组合形式为

{1,2,3} , {2,2,3} , {2,3,3}

讲一下这个不定方程到底怎么求。

请添加图片描述

#include <bits/stdc++.h> #define ll long long using namespace std; //贪心 int T, res; ll A1, B1, C1, D1, K1; ll A2, B2, C2, D2, M1; ll A3, B3, C3, D3, X1; bool check(ll X, ll Y, ll M) { ll l = -M - 3 * floor((X - M) / 2.0), r = -M - 3 * ceil((1 - M) / 2.0); if (r >= 1 && l <= Y) { return 1; } return 0; } bool solve(int k, ll K, ll M, ll X, int limit) { if (X == 0) { return (limit == 1); } if (k == 1) { if (X == 2 * M || (X % 2 == 0 && X / 2 <= K)) { return 1; } if (limit) { if (X <= K || (X % 3 == 0 && X / 3 <= K) || X == M) { return 1; } } return 0; } if (X >= M && solve(k - 1, K, M, X - M, limit)) return 1; if (X >= 2 * M && solve(k - 1, K, M, X - 2 * M, 1)) return 1; if (solve(k - 1, K, M, X, limit)) return 1; if (k == 2) { if (X % 2 == 0 && X / 2 <= 2 * K) return 1; if (X > 1 && X <= 3 * K) return 1; if (check(K, K, X)) return 1; if (limit) { if (X % 3 == 0 && X / 3 <= 2 * K) return 1; if (X <= 4 * K) return 1; } return 0; } if (k == 3) { if (X <= 6 * K) return 1; if (check(2 * K, K, X) || check(K, 2 * K, X)) return 1; return 0; } return 0; } int main() { // freopen("data.in","r",stdin); // freopen("dart.in","r",stdin); // freopen("dart.out","w",stdout); scanf("%d", &T); scanf("%lld%lld%lld%lld%lld", &A1, &B1, &C1, &D1, &K1); scanf("%lld%lld%lld%lld%lld", &A2, &B2, &C2, &D2, &M1); scanf("%lld%lld%lld%lld%lld", &A3, &B3, &C3, &D3, &X1); // solve(3,20,32,205,0); res += solve(3, K1, M1, X1, 0); for (int i = 2; i <= T; i++) { K1 = (((__int128)A1 * K1 * K1 + B1 * K1 % D1 + C1) % D1) + 20; M1 = (((__int128)A2 * M1 * M1 + B2 * M1 % D2 + C2) % D2) + 20; X1 = (((__int128)A3 * X1 * X1 + B3 * X1 % D3 + C3) % D3) + 20; res += solve(3, K1, M1, X1, 0); // if(solve(3,K1,M1,X1,0)) { // printf("%lld %lld %lld\n",K1,M1,X1); // } } printf("%d", res); } // 20 32 205 //1 //0 0 0 0 100 //0 0 0 0 1000 //0 0 0 0 1001

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530175.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(6)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示