北京师范大学第十二届程序设计竞赛

Posted jzdwajue

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了北京师范大学第十二届程序设计竞赛相关的知识,希望对你有一定的参考价值。

          感觉像是个人赛。只是要是个人赛的话他们真的是太牛了。。。

全然被虐爆了有没有啊。

          整体来说题目不是非常难,以下就粘一下代码吧。

           队友看的A,看完就发现了水题本质。可是敲的不是非常顺利。

。。是由于太久没做比赛么。。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define LL long long
#define inf 0x3f3f3f3f
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 100086;
const int INF = 0x3f3f3f3f;
int str[maxn];
int main()
{
    int n,i,j;
    int m,k;
    str[1]=0;
    for(i=2; i<100; i++)
    {
        str[i]=str[i-1]+i*i;
    }
    str[100]=inf;
    while(scanf("%d", &n) != EOF)
    {
        int tmp = 0;
        for(i=0; i<n; i++)
        {
            scanf("%d%d",&m,&k);
            tmp+=m*k;
        }
        int pos =0;
        for(i=1; i<=100; i++)
        {
            if(tmp>=str[i])pos = i;
        }
        printf("Team Liserious‘ rank is %d\n",pos);
    }
    return 0;
}

           B题看完就发现了,公式题一个,,,可是。读错题了。

。。经队友矫正,又读错了。。。=.=!!(什么情况,要gg了,过了非常久最终懂了题目让干什么,推了下公式就A了,题目给的是当前天和过后一天细菌的情况,然后问n天后的情况。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define LL long long
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
int main()
{
    LL b, a; int T;LL n;
    scanf("%d", &T);
    while(T --)
    {
        cin >> a >> b >> n;
        LL x, y;
        y = (b - a) / 2; x = a - y;
        n ++;
        double ans;
        if((n-1)/2 > (n-2)/2) y *= 3;
        ans = log10(x+y+0.0) + log10(3+0.0)*((n - 2) / 2);
        printf("%.7f\n", ans);
    }
}
          D题好像就是求一下向量夹角即可了。。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
const double pi=3.14159265358;
const double eps=1e-8;
int dblcmp(double x)
{
    if(x<-eps) return -1;
    if(x>eps) return 1;
    return 0;
}
struct point
{
    double x,y,k;
    point(double a=0,double b=0,double c=0)
    {
        x=a,y=b,k=c;
    }
    point operator-(const point &a)
    {
        return point(x-a.x,y-a.y,k);
    }
    void input()
    {
        scanf("%lf%lf%lf",&x,&y,&k);
    }
    bool friend operator<(const point &a,const point &b)
    {
        return a.k<b.k;
    }
} p[1010],st,en,s1,s2;
double dot(point a, point b)
{
    return a.x * b.x + a.y * b.y;
}
double cross(point a, point b)
{
    return a.x * b.y - a.y * b.x;
}
double angle(point a, point b)
{
    double res = acos(dot(a, b)/((sqrt(a.x * a.x + a.y * a.y)*sqrt(b.x * b.x + b.y * b.y))));
    if (dblcmp(cross(a, b)- 0) < 0) return 2 * pi - res;
    return res;
}
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++) p[i].input();
        sort(p,p+n);
        scanf("%lf%lf%lf%lf",&st.x,&st.y,&en.x,&en.y);
        s1=p[0]-p[1];
        s2=st-en;
        double ans=angle(s1,s2)/pi*180.00;
        if(ans>180.00) ans=360.00-ans;
        printf("%.3f\n",ans);
    }
}
           H居然11分钟就有人A掉了,太厉害了。。

推了下,既然是汉诺塔,就肯定是有递推关系了。

t[a+1] = 1/3*t[a]+2/3*(t[a] + 1 + f[a]);f[a]表示a个盘子的正常汉诺塔问题,即本来是在一个位置A,转移到C的步数。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define LL long long
#define MP make_pair
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 55;
const LL INF = 1ll << 60;
int main()
{
    int T, n;
    scanf("%d", &T);
    while(T --)
    {
        scanf("%d", &n);
        double ans = 2.0/3.0;
        for(int i = 2; i <= n; i ++)
        {
            ans = 1.0/3.0*ans + 2.0/3.0*(ans + (1ll << (i - 1)));
        }
        printf("%.2f\n", ans);
    }
}
 
        C题每次都询问右上角,显然询问值大于当前值的话,就能够删掉最右边一列,假设小于当前值的话就删掉最上边一行。就这样。。。输出非常特别啊

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define LL long long
#define MP make_pair
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 100100;
const int INF = 0x3f3f3f3f;
int main()
{
    int T, n, m, k;
    scanf("%d", &T);
    while(T --)
    {
        scanf("%d%d%d", &n, &m, &k);
        bool flag = false;
        int r = 1, c = m;
        while(r <= n && c >= 1)
        {
            printf("%d %d\n", r, c);fflush(stdout);
            int tmp; scanf("%d", &tmp);
            if(tmp == k)
            {
                flag = true;
                break;
            }
            if(tmp < k) r ++;
            else c --;
        }
        if(flag) puts("YES"),fflush(stdout);
        else puts("NO"),fflush(stdout);
    }
}

         J题正常搞肯定超时。这样的题。不是式子满足交换结合律之类,就是乘法特别,队友推出时满足这样 (A技术分享B)((AT).+1技术分享(BT).+1) = (A*((AT).+1))技术分享(B*((BT).+1)),这样就妥妥的能AC了。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define LL long long
#define MP make_pair
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 55;
LL ans[3000][3000];
struct Mr
{
    LL m[maxn][maxn];
    int r, c;
    void pt()
    {
        for(int i = 0; i < r; i ++)
            for(int j = 0; j < c; j ++)
                printf("%lld%c", m[i][j], j == c - 1?

‘\n‘ : ‘ ‘); } }; Mr Tadd1(Mr a) { Mr ret; ret.r = a.c; ret.c = a.r; for(int i = 0; i < a.r; i ++) for(int j = 0; j < a.c; j ++) { ret.m[j][i] = a.m[i][j] + 1; } return ret; } Mr Mul(Mr a, Mr b) { Mr ret; ret.r = a.r; ret.c = b.c; for(int i = 0; i < a.r; i ++) { for(int j = 0; j < b.c; j ++) { ret.m[i][j] = 0; for(int k = 0; k < a.c; k ++) { ret.m[i][j] += a.m[i][k] * b.m[k][j]; } } } return ret; } void OR(Mr a, Mr b) { for(int i = 0; i < a.r; i ++) { for(int j = 0; j < a.c; j ++) { for(int k = 0; k < b.r; k ++) { for(int s = 0; s < b.c; s ++) { ans[i*b.r+k][j*b.c+s] = a.m[i][j] * b.m[k][s]; } } } } } Mr a, at, b, bt; int main() { int T, n, m, p, q; scanf("%d", &T); while(T --) { scanf("%d%d%d%d", &n, &m, &p, &q); a.r = n, a.c = m; b.r = p, b.c = q; for(int i = 0; i < n; i ++) { for(int j = 0; j < m; j ++) scanf("%lld", &a.m[i][j]); } for(int i = 0; i < p; i ++) { for(int j = 0; j < q; j ++) scanf("%lld", &b.m[i][j]); } at = Tadd1(a); bt = Tadd1(b); OR(Mul(a, at), Mul(b, bt)); for(int i = 0; i < n*p; i ++) { for(int j = 0; j < n*p; j ++) { printf("%lld%c", ans[i][j], j == n*p - 1 ?

‘\n‘ : ‘ ‘); } } return 0; }

        F题dp一枚。每次枚举出每组的情况。然后结合前面能组成的情况,dp就能够了。

dp[i]表示sum个位置哪个位置被占用了。时间复杂度不明。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define LL long long
#define MP make_pair
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 25;
LL dp[(1<<20)+100];
vector<int> a[maxn], now, nxt;
int sum, n, b[7];
void dfs(int idx)
{
    if(idx >= n) return;
    int sz = a[idx].size(), ca = 0;
    for(int j = 0; j < sz; j ++)
        b[j]  = j, ca += a[idx][j];
    b[sz] = 0;
    nxt.clear();
    for(int i = 0; i < sum; i ++)
    {
        do
        {
            int fu = 0, ta = i;
            if(i + ca - a[idx][b[0]] >= sum) continue;
            for(int j = 0; j < sz; j ++)
            {
                fu |= (1 << (ta));
                ta += a[idx][b[j + 1]];
            }
            for(int j = 0; j < now.size(); j ++)
                if(!(fu&now[j]))
                {
                    if(!dp[fu|now[j]]) nxt.push_back(fu|now[j]);
                    dp[fu|now[j]] += dp[now[j]];
                }
        } while(next_permutation(b, b + sz));
    }
    now.clear();
    for(int i = 0; i < nxt.size(); i ++) now.push_back(nxt[i]);
    dfs(idx + 1);
}
int main()
{
    while(scanf("%d", &n) != EOF)
    {
        sum = 0;
        for(int i = 0; i < n; i ++)
        {
            int m, tmp;a[i].clear();
            scanf("%d", &m);
            sum += m;
            while(m --)
            {
                scanf("%d", &tmp);
                a[i].push_back(tmp);
            }
        }
        now.clear();
        CLR(dp, 0);
        now.push_back(0); dp[0] = 1;
        dfs(0);
        printf("%lld\n", dp[(1<<sum)-1]);
    }
}

       G题有类似的题目,错到最后。发现模板有问题。。。汗。赛后两分钟换了个模板就A了。。。闹哪样啊这是。

(代码风格能够看出。。

。显然不是我做的,全然不知道怎么做啊=,=!!)

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
double Dis(double x1, double y1, double x2, double y2)
{
    double dx=x1-x2;
    double dy=y1-y2;
    return sqrt(dx*dx+dy*dy);
}
void Get_KL(double L, double x, double y, int &k, int &l, double &cd)
{
    k=floor((2.0*x)/(3.0*L));
    l=floor((2.0*y)/(sqrt(3.0)*L));
    double d1, d2, x1, y1, x2, y2;
    if ((k+l)&1)
    {
        x1=k*L*1.5;
        y1=(l+1.0)*L*sqrt(3.0)*0.5;
        x2=(k+1.0)*L*1.5;
        y2=l*L*sqrt(3.0)*0.5;
        d1=Dis(x1,y1, x,y);
        d2=Dis(x2,y2, x,y);
        if (d1>d2)
        {
            k++;
            cd=d2;
        }
        else
        {
            l++;
            cd=d1;
        }
    }
    else
    {
        x1=k*L*1.5;
        y1=l*L*sqrt(3.0)*0.5;
        x2=(k+1.0)*L*1.5;
        y2=(l+1.0)*L*sqrt(3.0)*0.5;
        d1=Dis(x1,y1, x,y);
        d2=Dis(x2,y2, x,y);
        if (d1>d2)
        {
            k++,l++;
            cd=d2;
        }
        else cd=d1;
    }
}
int My_Abs(int x)
{
    if (x<0) return -x;
    return x;
}
int main (void)
{
    double L, x1, y1, x2, y2, cd1, cd2;
    int k1, l1, k2, l2, ans;
    int t;
    scanf("%d",&t);
    while (t--)
    {
        scanf("%lf %lf %lf %lf %lf",&L,&y1,&x1,&y2,&x2);
        y1=-y1,y2=-y2;
        Get_KL(L, x1, y1, k1, l1, cd1);
        Get_KL(L, x2, y2, k2, l2, cd2);
        if (k1==k2&&l1==l2) printf("%d\n",0);
        else
        {
            ans=0;
            if (My_Abs(k1-k2) > My_Abs(l1-l2))
                ans=My_Abs(k1-k2);
            else ans=My_Abs(k1-k2)+(My_Abs(l1-l2)-My_Abs(k1-k2))/2;
            printf("%d\n", ans);
        }
    }
    return 0;
}










以上是关于北京师范大学第十二届程序设计竞赛的主要内容,如果未能解决你的问题,请参考以下文章

湖南省第十二届大学生计算机程序设计竞赛 G Parenthesis

“山大地纬杯”第十二届山东省ICPC大学生程序设计竞赛 AHK

湖南省第十二届大学生计算机程序设计竞赛 A 2016

湖南省第十二届大学生计算机程序设计竞赛---Parenthesis(线段树求区间最值)

湖南省第十二届大学生计算机程序设计竞赛 problem A 2016

模拟数学CSU 1803 2016 (2016湖南省第十二届大学生计算机程序设计竞赛)