牛客,第二十届北京师范大学程序设计竞赛,签到题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题

2021第7届中国大学生程序设计竞赛CCPC广州站, 签到题4题

2021第7届中国大学生程序设计竞赛CCPC广州站, 签到题4题