FJ第八届省赛

Problem 2272 Frog

这个题随便暴力

Problem 2273 Triangles

我的做法是这样子的,因为要判断两个三角形的位置关系,所以判断相交的话是最简单的因为有板子啊,然后就是判断包含的关系

要是一个三角形包含另一个三角形,那么他们三个点都在这个大三角形的内部,可以发现要是这个点垂直于x轴做垂线和另外一个三角形的至少两个边相交,那么这个点肯定在这这个三角形的内部,所以我们有转化成了线段的相交,因为我只有一个线段相交的板子。

Problem 2274 DotA and LOL

不会,估计不会补了。

Problem 2275 Game

有两个人,每个人手中一个数,每个人轮流操作自己数,第一个人先开始。

有两种个操作:  使这个数倒过来  假如这个数为 1232 倒过来以后 2321

                           使这个数除以10,假如这个数为345,除以10以后为34

要是在有限次数内,If A=B after any player’s action,那么第一个人赢

题解:  这个数据太水了,我的错误的代码都过了,但是我还是加强了一下自己的代码。随便找个数举个栗子就行了。

就是一个裸的kmp板子

#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn=5e5;
char s1[maxn],s2[maxn],b1[maxn],b2[maxn];
int f[maxn];

void getFail(char *P,int *f)
{
    int m=strlen(P);
    f[0]=0; f[1]=0;
    for(int i=1;i<m;i++)
    {
        int j=f[i];
        while(j&&P[i]!=P[j]) j=f[j];
        f[i+1]=P[i]==P[j]?j+1:0;
    }
}
int find(char *T,char *P,int *f)
{
    int n=strlen(T),m=strlen(P);
    getFail(P,f);
    int j=0;
    for(int i=0;i<n;i++)
    {
        while(j&&P[j]!=T[i]) j=f[j];
        if(P[j]==T[i]) j++;
        if(j==m) return 1;
    }
    return 0;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(b1,'\0',sizeof(b1));
        memset(b2,'\0',sizeof(b2));
        scanf("%s%s",s1,s2);
        int flag=0;
        int sz=strlen(s1);
        for(int i=sz-1;i>=0;i--)
        {
            if(s1[i]=='0'&&i!=0)
            {
                sz--;
            }
            else
            break;
        }
        for(int i=0;i<sz;i++)
        {
            b1[i]=s1[i];
        }
        sz=strlen(s2);
        for(int i=sz-1;i>0;i--)
        {
            if(s2[i]=='0'&&i!=0)
            {
                sz--;
            }
            else break;
        }
        for(int i=0;i<sz;i++) b2[i]=s2[i];
        int sz1=strlen(b1);
        int sz2=strlen(b2);
        //printf("%d %d\n",sz1,sz2);
        if(sz2>sz1)
        {
            printf("Bob\n"); continue;
        }
        else if(find(b1,b2,f)||!strcmp(b2,"0"))
        {
            printf("Alice\n");
        }
        else{
            reverse(b2,b2+sz2);
            if(find(b1,b2,f)) printf("Alice\n");
            else printf("Bob\n");
        }
    }
}

 Problem E Doctor

  题目太长,应该很难。

 

   Problem F Change

     这个东西好像是树链剖分,今天争取把这个坑填了。

 

 Problem 2278 YYS

   我认为这个题是这些题中质量最高的,虽然不是最难的。 

   我们可以发现的是这些卡片都是一样的,对这个题来说本质上是一样的,独立考虑发现并不是那么简单的事情,那么我们把这些卡片合起来考虑,

   那么第一次我们肯定会发现一个我们没有的卡片,第二次发现我们没有的卡片的概率是(n-1)/n,那第三次概率就是(n-2)/n,那么拿第二次发现我们没有的概率

   来说明问题,我们要求的是(期望)需要多少次才能发现我们的第二个卡片。Ex=1*x+2*(x-1)*3*(x-1)*(x-1)*x,然后就是把x提出来然后错位相减,其实就是一个几何分      布,为了这个题和高中的小朋友扯了1个小时淡,突然感觉还是年轻好啊。

 

  Problem 2280 Magic

  字典树板子题

  

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
const int maxnode=1e6+3;
int ch[maxnode][30];
vector<int>v[maxnode];
char s[3000][3000];
int w[1200];
struct Tire
{
    int sz;
    Tire()
    {
        sz=1;
        memset(ch[0],0,sizeof(ch[0]));
    }
    int idx(char c) {return c-'a';}
    void insert(char *s,int id)
    {
       // printf("***\n");
        int u=0,n=strlen(s);
        for(int i=0;i<n;i++)
        {
            int flag=0;
            int c=idx(s[i]);
            if(!ch[u][c])
            {
                flag=1;
                memset(ch[sz],0,sizeof(ch[sz]));
                v[sz].clear();

                ch[u][c]=sz++;
            }
            u=ch[u][c];
            v[u].push_back(id);
        }
    }
    void search(char *s,int k)
    {
        int ans=0;
        int u=0,n=strlen(s);
        for(int i=0;i<n;i++)
        {
            int c=idx(s[i]);
            u=ch[u][c];
        }
        int sz=v[u].size();
        for(int i=0;i<sz;i++)
        {
            int id=v[u][i];
            if(w[id]<=w[k])
            {
                ans++;
            }
        }
        printf("%d\n",ans);
    }
};
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,q;
        Tire tire;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s[i]);
            scanf("%d",&w[i]);
            int l=strlen(s[i]);
            reverse(s[i],s[i]+l);
            tire.insert(s[i],i);
        }

        scanf("%d",&q);
        while(q--)
        {
            int cur;
            scanf("%d",&cur);
            if(cur==1)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                w[x]=y;
            }
            else
            {
                int id;
                scanf("%d",&id);
             //   printf("%s\n",s[id]);
                tire.search(s[id],id);
            }
        }
    }
}

 Problem J Trades

  sum=sum%a[i-1]+sum/a[j-1]*max(a[i-1],a[i]),就是贪心,但是要高精度。

 

   Problem K Wand

  用到错位排序,但是时限好像很松啊,我1e8都不超时。

  f[n]=(n-1)*(f[n]+f[n-1])

 

  Problem L Tic-Tac-Toe

  

 

  问某个人是不是能在两部之内获得胜利,A先走,B再走,A再走停止

  我的思路,要是A走了一步,要是他可以产生两个以上必胜点,那就肯定赢。就是考虑几个情况。

   

 

posted @ 2017-07-24 16:57  Heilce  阅读(303)  评论(3编辑  收藏  举报