暑假集训CSP模拟一

赛时rank 14 T1 0,T2 0,T3 100,T4 0

T1大模拟出题人_______

T1 Start

大模拟,注意细节。

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#ifdef LOCAL
FILE *InFile = freopen("in.in","r",stdin),*OutFile = freopen("out.out","w",stdout);
#else
#endif
using ll = long long;using ull = unsigned long long;
int n,m,k,now,nowp,sgn = 1;
struct node{
string name;
vector<string> nor,abnor;
bool Double = false;
}a[40];
queue<string> Card;
inline bool is_normal(string s){return (s!="PASS"&&s!="DOUBLE"&&s!="TURN");}
inline void Print_Used(string name,string card){cout<<name+" used "+card+",now p="<<nowp<<".\n";}
inline void change_now(int &now,int delta){now += delta;if(now <= 0) now += n;if(now > n) now -= n;}
inline void get_new_card(int now){
string s = Card.front();Card.pop();
if(is_normal(s)) a[now].nor.push_back(s);
else a[now].abnor.push_back(s);
}
inline bool del_double_by_solve(string aim){
for(auto i = a[now].abnor.begin();i != a[now].abnor.end(); ++i)
if((*i) == "") a[now].abnor.erase(i);
for(auto i = a[now].abnor.begin();i != a[now].abnor.end();++i){
if((*i) == aim){
Print_Used(a[now].name,*i);
a[now].abnor.erase(i);
get_new_card(now);
a[now].Double = false;
return true;
}
}
return false;
}
inline int get_order(char s){
if(s == 'C') return 4;
else if(s == 'A') return 3;
else if(s == 'B') return 2;
else if(s == 'D') return 1;
else return 0;
}
inline int get_nxtp(int p,string s){
int x = 0;
for(int i = 1;i < s.size(); ++i) x = x*10+(s[i]-'0');
if(s[0] == 'A') return p+x;
else if(s[0] == 'B') return p-x;
else if(s[0] == 'C') return p*x;
else if(s[0] == 'D') return (int)(floor(1.0*p/x));
else return x;
}
inline void Print_Lost(string name){cout<<name+" lost the game.\n";}
inline int Get_Order(char s){
if(s == 'D') return 4;
if(s == 'B') return 3;
if(s == 'A') return 2;
if(s == 'C') return 1;
return 0;
}
inline void Work(){
while(true){
// for(auto i:a[now].nor) cout<<i<<' ';
// cout<<' ';
// for(auto i:a[now].abnor) cout<<i<<' ';
if(a[now].Double){
if(del_double_by_solve("PASS")) change_now(now,sgn),a[now].Double = true;
else if(del_double_by_solve("TURN")) sgn = -sgn,change_now(now,sgn),a[now].Double = true;
else if(del_double_by_solve("DOUBLE")) change_now(now,sgn),a[now].Double = true;
else{
pair<int,pair<string,vector<string>::iterator> > max1;
max1.first = INT_MAX;
for(auto i = a[now].nor.begin();i != a[now].nor.end();++i){
if((*i) == ""){continue;}
int emm = get_nxtp(nowp,*i);
if(emm < max1.first || (emm == max1.first && Get_Order(max1.second.first[0])<Get_Order((*i)[0])))
max1 = make_pair(emm,make_pair(*i,i));
}
if(max1.first > 99){
vector<string>().swap(a[now].abnor);
vector<string>().swap(a[now].nor);
for(int i = 1;i <= 3; ++i) get_new_card(now);
return Print_Lost(a[now].name),void();
}
else{
nowp = max1.first,
Print_Used(a[now].name,max1.second.first),
get_new_card(now),
a[now].nor.erase(max1.second.second);
}
a[now].Double = false;
goto K;
}
continue;
}
else{
K:;
pair<int,pair<string,vector<string>::iterator> > max1;
max1.first = INT_MIN;
for(auto i = a[now].nor.begin();i != a[now].nor.end(); ++i){
if((*i) == "") {continue;}
int emm = get_nxtp(nowp,*i);
if(emm > 99) continue;
if(emm > max1.first || (emm == max1.first && get_order((*i)[0]) > get_order(max1.second.first[0])))
max1 = make_pair(emm,make_pair(*i,i));
}
if(max1.first != INT_MIN){
nowp = max1.first;
Print_Used(a[now].name,max1.second.first);
a[now].nor.erase(max1.second.second);
get_new_card(now);
change_now(now,sgn*1);
}
else{
if(del_double_by_solve("PASS")) change_now(now,sgn);
else if(del_double_by_solve("TURN")) sgn = -sgn,change_now(now,sgn);
else if(del_double_by_solve("DOUBLE")) change_now(now,sgn),a[now].Double = true;
else{
vector<string>().swap(a[now].abnor);
vector<string>().swap(a[now].nor);
for(int i = 1;i <= 3; ++i) get_new_card(now);
return Print_Lost(a[now].name),void();
}
}
}
}
}
signed main(){
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
cin>>n>>m>>k;
for(int i = 1;i <= n; ++i){
cin>>a[i].name;
for(int j = 1;j <= 3; ++j){
string s;cin>>s;
if(is_normal(s)) a[i].nor.push_back(s);
else a[i].abnor.push_back(s);
}
}
for(int i = 1;i <= k; ++i){
string s;cin>>s;Card.push(s);
}
now = 1;
for(int i = 1;i <= m; ++i){
cout<<"Round "<<i<<":\n";
Work();
for(int j = 1;j <= n; ++j) a[j].Double = false;
nowp = 0;
sgn = 1;
}
}

T2 mine

递推,考虑当前位的贡献只与当前位,上一位,下一位有关

fi,0/1/2表示第i位的下一位没有/有雷,第i位是雷时的方案数

当前位是0时,fi,0=fi1,0

当前位是1时,fi,0=fi1,2,fi,1=fi1,0

当前位是2时,fi,0=fi1,2

当前位是时,fi,2=fi1,1+fi1,2

当前位是?时,fi,2=fi1,1+fi1,2fi,0=fi,1=fi1,0+fi1,2

答案为fn,0+fn,2

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#ifdef LOCAL
FILE *InFile = freopen("in.in","r",stdin),*OutFile = freopen("out.out","w",stdout);
#else
#endif
using ll = long long;using ull = unsigned long long;
const int N = 1e6 + 10 ,mod = 1e9 + 7;
char s[N];
int n,f[N][3];
signed main(){
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
cin>>(s+1);
n = strlen(s+1);
f[0][0] = f[0][1] = 1;
for(int i = 1;i <= n; ++i){
if(s[i] == '0') f[i][0] = f[i-1][0];
if(s[i] == '1') f[i][0] = f[i-1][2],f[i][1] = f[i-1][0];
if(s[i] == '2') f[i][1] = f[i-1][2];
if(s[i] == '*') f[i][2] = (f[i-1][1]+f[i-1][2])%mod;
if(s[i] == '?') f[i][2] = f[i-1][1] + f[i-1][2],f[i][0] = f[i][1] = (f[i-1][0]+f[i-1][2])%mod;
f[i][0]%=mod;f[i][1]%=mod;f[i][2]%=mod;
}
cout<<(0ll+f[n][0]+f[n][2])%mod<<'\n';
}

T3 小凯的疑惑

gcd(x,y)1时,直接输出-1

证明显然,假设当前有一个数c,那么若有ax+by=c,则一定有gcd(x,y)c,若gcd(x,y)1,则一定可以找出无穷个数,使得gcd(x,y)c

由于数据非常小,我们可以直接O(n)水过……

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#ifdef LOCAL
FILE *InFile = freopen("in.in","r",stdin),*OutFile = freopen("out.out","w",stdout);
#else
#endif
long long LCM(int a,int b){
return 1ll * a / __gcd(a,b) * b;
}
signed main(){
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
int x,y;
cin>>x>>y;
if(x > y) swap(x,y);
if(x == 1) return puts("0"),0;
if(__gcd(x,y) != 1) return puts("-1"),0;
long long lcm = LCM(x,y),a = 0;
for(int i = 0;;++i){
long long emm = 1ll * i * y;
if(emm + x > lcm) break;
a += (lcm-emm-x+1)/x+1;
}
cout<<lcm-x+2-a<<'\n';
}

but,正解还是有必要想的

考虑这个暴力的实质,是将给数轴上标出的东西减去。

image

暴力是枚举x+0y,x+1y,x+2y,

列出式子,化一下就有了i=0x1iyx

化简,两边同时乘上x,再将向下取整化成mod的形式

得到xi=0x1iyx=i=0x1iyi=0x1(iymodx)

等差数列求和,就有x(x1)y2x(x1)2x

(x1)(y1)2

T4 春节十二响

简单的贪心,看代码

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#ifdef LOCAL
FILE *InFile = freopen("in.in","r",stdin),*OutFile = freopen("out.out","w",stdout);
#else
#endif
using ll = long long;using ull = unsigned long long;
const int N = 2e5 + 10;
struct EDGE{int to,next;}edge[N<<1];
int head[N],cnt,d[N],son[N];
inline void add(int u,int v){edge[++cnt] = {v,head[u]};head[u] = cnt;}
bitset<N> vis;
int n,a[N];
priority_queue<int> q[N];
ll ans = 0;
inline void Merge(int x,int y){
priority_queue<int> p;
while(q[y].size()){
p.push(max(q[x].top(),q[y].top()));
q[x].pop();q[y].pop();
}
while(p.size()) q[x].push(p.top()),p.pop();
}
void dfs1(int x){
d[x] = 1;
for(int i = head[x]; i;i = edge[i].next){
int y = edge[i].to;
dfs1(y);
if(d[y] > d[son[x]]) son[x] = y;
d[x] = max(d[x],d[y]+1);
}
}
void dfs(int x){
if(son[x]){
dfs(son[x]);
q[x].swap(q[son[x]]);
}
for(int i = head[x]; i;i = edge[i].next){
int y = edge[i].to;
if(y == son[x]) continue;
dfs(y);
Merge(x,y);
}
q[x].push(a[x]);
}
signed main(){
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
cin>>n;
for(int i = 1;i <= n; ++i) cin>>a[i];
for(int i = 2,f;i <= n; ++i){
cin>>f;
add(f,i);
}
dfs1(1);
dfs(1);
while(q[1].size()) ans += q[1].top(),q[1].pop();
cout<<ans<<'\n';
}
posted @   CuFeO4  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探
点击右上角即可分享
微信分享提示