牛客,第二十届北京师范大学程序设计竞赛,签到题7题
Posted 小哈里
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客,第二十届北京师范大学程序设计竞赛,签到题7题相关的知识,希望对你有一定的参考价值。
序
题号 标题 已通过代码 通过率 团队的状态
A 小凯的疑惑 点击查看 434/745 通过
B 幻象踩花 点击查看 121/434 通过
C 跳刀抓人 点击查看 26/178 通过
D 真正的卡尔 点击查看 115/714 通过
E 刷新的艺术 点击查看 31/479 通过
F 最后的战役 点击查看 1/39 未通过
G 随机数生成器 点击查看 1/20 未通过
H 字符串 点击查看 25/130 通过
I 修罗牌浪 点击查看 1/4 未通过
J 集合论 点击查看 72/242 通过
K 有趣的矩阵 点击查看 6/20 未通过
A、小凯的疑惑
- NOIP2017D1T1原题,小学奥数公式,结论是ab-a-b。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e9+7;
LL ksm(LL a, LL b)if(b==0)return 1;LL ns=ksm(a,b>>1);ns=ns*ns%mod;if(b&1)ns=ns*a%mod;return ns;
void EXGCD(int a, int b, int &d, int &x, int & y, int MOD) if (b==0) d = a; x = 1; y = 0; else EXGCD(b, a % b, d, y, x, MOD); y -= x * (a / b);
int inv(int a, int MOD) int d=0, x=0, y=0; EXGCD(a, MOD, d, x, y, MOD); return d == 1 ? (x + MOD) % MOD : -1;
int main()
LL a, b; cin>>a>>b;
cout<<a*b-a-b;
return 0;
B、幻象踩花
- 画图以后结论题,注意特判
- 开始思路错了几个方向,后来特判想了好一会儿,
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const double pi = acos(-1);
int main()
//cout<<area(point2,0,1, point-2,-2,2.8)<<"\\n";
int T; cin>>T;
while(T--)
LL R, r, x, y; cin>>R>>r>>x>>y;
if(x*x+y*y>(R+r)*(R+r) || x*x+y*y<=(R-r)*(R-r))
printf("%.10lf\\n",0 ); continue;
double d = sqrt(x*x+y*y);
double t = (x*x+y*y+R*R-r*r)*1.0/(2*d*R);
//cout<<t<<"\\n";
double ans = acos(t)/pi*2;
printf("%.10lf\\n",ans );
return 0;
C、跳刀抓人
- 暴力bfs,对于闪烁操作,在每个节点中多维护一个time表示当前是第几秒,转移时特判当前能否转移。
- 没有判断能否转移,直接全部暴力转移了,WA了好久
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const double pi = acos(-1);
struct nodeint x, y, t, time;;
struct cmp
bool operator()(node a, node b) return a.t > b.t;
;
priority_queue<node, vector<node>, cmp>q;
int xx[] = 0,0,-1,1;
int yy[] = 1,-1,0,0;
char a[110][110];
int vis[110][110][10];
int main()
int n, m; cin>>n>>m;
node st, ed;
for(int i = 1; i <= n; i++)
//scanf("%s",a[i]+1);
for(int j = 1; j <= m; j++)
cin>>a[i][j];
if(a[i][j]=='A')st = nodei,j,0,7;
if(a[i][j]=='B')ed = nodei,j,0,7;
// for(int i = 1; i <= n; i++)
// for(int j = 1; j <= m; j++)
// cout<<a[i][j];
//
// cout<<"\\n";
//
//queue<node>q;
q.push(st);
while (q.size())
node t = q.top(); q.pop();
t.time = min(t.time, 7);
if(vis[t.x][t.y][t.time])continue;
vis[t.x][t.y][min(t.time,7)] = 1;
if(a[t.x][t.y]=='B')
cout<<t.t<<"\\n";
return 0;
for(int dx = -3; dx <= 3; dx++)
for(int dy=-3; dy<=3; dy++)
if(dx==0&&dy==0)continue;
int nx=t.x+dx, ny = t.y+dy;
if(nx<1||nx>n||ny<1||ny>m)continue;
if(a[nx][ny]=='#')continue;
if(t.time==7)q.push(nx,ny,t.t+1,0);
// int nx = t.x+dx, ny = t.y+dy;
// if(nx<1||nx>n||ny<1||ny>m)continue;
// if(a[nx][ny]=='#'|| vis[t.x][t.y][nx][ny])continue;
// int dd = abs(dx)+abs(dy), nt;
// if(dd==1)nt = 1;else nt=8;
// if(ok==0)nt=1;
// q.push(nodenx,ny,t.t+nt);
// vis[t.x][t.y][nx][ny] = 1;
int d = 7-t.time;
if(t.time<7)q.push(t.x,t.y,t.t+d,7);
for(int i = 0; i < 4; i++)
int nx = t.x+xx[i], ny = t.y+yy[i];
if(nx<1||nx>n||ny<1||ny>m)continue;
if(a[nx][ny]=='#')continue;
q.push(nx,ny,t.t + 1,t.time + 1);
cout<<-1<<'\\n';
return 0;
D、真正的卡尔
- 排列组合结论题,打表找规律得到递推公式
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 998244353;
const int maxn = 1010;
LL f[maxn][maxn];
int main()
for(int i = 1; i <= 1000; i++)f[i][1] = i, f[1][i] = 1;
for(int i = 2; i <= 1000; i++)
for(int j = 2; j <= 1000; j++)
f[i][j] = (f[i-1][j]+f[i][j-1])%mod;
int T; cin>>T;
while(T--)
int a, b; cin>>a>>b;
cout<<f[a][b]<<"\\n";
return 0;
E、刷新的艺术
- 分类讨论结论题,开始有两种情况没有想到
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const double pi = acos(-1);
int gcd(int a, int b) return b==0 ? a : gcd(b,a%b);
void out(int x, int y)
if(x%y==0)cout<<x/y<<"\\n";
else cout<<x/gcd(x,y)<<"/"<<y/gcd(x,y)<<"\\n";
int main()
int T; cin>>T;
while(T--)
int a, b; cin>>a>>b;
if(a>b)
//cout<<b<<"\\n"; continue;
if(a>b*2)cout<<b<<"\\n";else out(a,2);
continue;
//out(b, b/a+1);
if(b%a==0)out(b,b/a+1);
else
int c = b/a+1;
if(b*1.0/c < a*1.0*c/(c+1))out(b,c);
else out(a*c,c+1);
return 0;
H、字符串
- KMP暴力出所有区间,然后贪心,按照左端点排序扫一遍更新答案
- 扫的时候需要考虑区间右边的重合情况,额外开个队列维护
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e7+100;
int n, m, k; string s,p;
struct nodeint l, r;;
bool cmp(node x, node y)
return x.l<y.l;
vector<node>vc;
int nxt[maxn];
void pre_next(string p)
int j = 0; //j表示到i-1为止的最长前缀的下标
for(int i = 2; i < p.size(); i++)
//用到j为止的最长公共前缀的下标,尝试去匹配下一个字母
while(j && p[i]!=p[j+1])j = nxt[j];
if(p[i]==p[j+1])j++;
nxt[i] = j;
void kmp(string s, string p)
int j = 0;
for(int i = 1; i <= s.size()-1; i++)
while(j && s[i]!=p[j+1])j = nxt[j];//不停的去找直到s[i]能匹配上下一个
if(s[i]==p[j+1])j++;//匹配上了就加一
if(j==p.size()-1)//匹配完了
int t = i-p.size()+1;
//cout<<t+1<<" ";
vc.push_back(nodet+1,t+m);
j = nxt[j];
int main()
cin>>n>>m>>k>>s>>p;
s="0"+s; p="0"+p;
pre_next(p);
kmp(s,p);
sort(vc.begin(),vc.end(),cmp);
// for(node t : vc)
// cout<<t.l<<" "<<t.r<<"\\n";
//
queue<int>qu;
int cnt = 1, cc = 1;
qu.push(vc[0].r);
for(int i = 1; i < vc.size(); i++)
if(vc[i].l > qu.front())
while(vc[i].l > qu.front()&&qu.size()>1)
qu.pop();
cc--;
cnt++;
cc++;
qu.push(vc[i].r);
//cout<<vc[i].l<<" "<<vc[i].r<<" "<<cc<<22<<'\\n';
else
while(cc>=k&&qu.size()>1&&vc[i].l>qu.front())
qu.pop();
cc--;
if(cc<k)
cnt++;
qu.push(vc[i].r);
cc++;
//cout<<vc[i].l<<" "<<vc[i].r<<" "<<cc<<'\\n';
第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明),签到题3题
第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明),签到题3题
2021第7届中国大学生程序设计竞赛CCPC桂林站, 签到题5题
2021第7届中国大学生程序设计竞赛CCPC桂林站, 签到题5题