赛时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
递推,考虑当前位的贡献只与当前位,上一位,下一位有关
设\(f_{i,0/1/2}\)表示第\(i\)位的下一位没有/有雷,第\(i\)位是雷时的方案数
当前位是\(0\)时,\(f_{i,0}=f_{i-1,0}\)
当前位是\(1\)时,\(f_{i,0} = f_{i-1,2},f_{i,1}=f_{i-1,0}\)
当前位是\(2\)时,\(f_{i,0}=f_{i-1,2}\)
当前位是\(*\)时,\(f_{i,2}=f_{i-1,1}+f_{i-1,2}\)
当前位是\(?\)时,\(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}\)
答案为\(f_{n,0}+f_{n,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)\ne -1\)时,直接输出-1
证明显然,假设当前有一个数\(c\),那么若有\(ax+by=c\),则一定有\(gcd(x,y)\mid c\),若\(gcd(x,y)\ne 1\),则一定可以找出无穷个数,使得\(gcd(x,y)\nmid 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,正解还是有必要想的
考虑这个暴力的实质,是将给数轴上标出的东西减去。
暴力是枚举\(x+0y,x+1y,x+2y,\ldots\)
列出式子,化一下就有了\(\sum_{i=0}^{x-1}\left\lfloor\frac{iy}{x}\right\rfloor\)
化简,两边同时乘上x,再将向下取整化成mod的形式
得到\(x\sum_{i=0}^{x-1}\left\lfloor\frac{iy}{x}\right\rfloor=\sum_{i=0}^{x-1}iy-\sum_{i=0}^{x-1}(iy\mod x)\)
等差数列求和,就有\(\frac{\frac{x(x-1)y}{2}-\frac{x(x-1)}{2}}{x}\)
即\(\frac{(x-1)(y-1)}{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';
}