Day1 T1

签到题,模拟一下随便写就能过。

不过小心像我一样表打错傻逼的调了10min。

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
int La=0,Lb=0,N=0;
int xl_a[205]={0},xl_b[205]={0};
int check[5][5]={{0,-1,1,1,-1},{1,0,-1,1,-1},{-1,1,0,-1,1},{-1,-1,1,0,1},{1,1,-1,-1,0}};
int main(void)
{
    freopen("rps.in","r",stdin);
    freopen("rps.out","w",stdout);
    scanf("%d%d%d",&N,&La,&Lb);
    for(int i=1;i<=La;i++)scanf("%d",&xl_a[i]);
    for(int i=1;i<=Lb;i++)scanf("%d",&xl_b[i]);
    int a=0,b=0,ans_a=0,ans_b=0;
    for(int i=1;i<=N;i++)
    {
        a=xl_a[i%La];
        if(!(i%La))a=xl_a[La];
        b=xl_b[i%Lb];
        if(!(i%Lb))b=xl_b[Lb];
        if(check[a][b]==1){ans_a++;continue;}
        if(check[a][b]!=0){ans_b++;;continue;}
    }
    printf("%d %d",ans_a,ans_b);
    return 0;
}
View Code

T2

没什么难度……不知道为什么能卡当时的我只拿70分。

大概是不知道n个点n-1条边就是树?

最开始写代码的时候没考虑兄弟节点的情况……后面紧急补上去了,还好发现了不然岂不是又得炸。

一涉及到取模我的代码风格就变得乱七八糟。

简述一下,我们对这棵树从1开始dfs,每到一个节点,就先更新答案(和它父亲的父亲)。

然后枚举它的儿子节点,记录两个参数,max_son和tot,max_son是它儿子节点中权值最大的那个,tot是它所有儿子的权值和。

max_son是更新第一个最大值的答案的,tot是更新第二个答案的。

顺便提醒一下,因为题面上说的是有序点对,所以说我们每次更新第二个答案的时候都要记住乘个2……【血泪教训】

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
struct lb
{
    int nw;
    int nxt;
};
lb line[400003];
int n=0,cnt=0,val[200003]={0},head[200003]={0};
int fa[200003]={0},ans1=0,ans2=0;
void add(int f,int t);
void dfs(int nw);
int main(void)
{
    freopen("link.in","r",stdin);
    freopen("link.out","w",stdout);
    scanf("%d",&n);
    int a=0,b=0;
    for(int i=1;i<=n-1;i++)
    {
        scanf("%d%d",&a,&b);
        add(a,b);
        add(b,a);
    }
    for(int i=1;i<=n;i++)scanf("%d",&val[i]);
    fa[1]=0;
    dfs(1);
    printf("%d %d",ans1,ans2);
    return 0;
}

void add(int f,int t)
{
    line[++cnt].nw=t;
    line[cnt].nxt=head[f];
    head[f]=cnt;
    return;
}

void dfs(int nw)
{
    if(nw>n)return;
    if(fa[fa[nw]])
    {
        ans1=max(ans1,val[nw]*val[fa[fa[nw]]]);
        ans2+=val[nw]*val[fa[fa[nw]]]*2;
        ans2%=10007;
    }
    int next=0,max_son=0,tot=0;
    for(int i=head[nw];i>0;i=line[i].nxt)
    {
        next=line[i].nw;
        if(next==fa[nw])continue;
        ans1=max(ans1,val[next]*max_son);
        ans2+=(tot%10007)*val[next]*2;
        ans2%=10007;
        max_son=max(max_son,val[next]);
        tot+=val[next];
        tot%=10007;
        fa[next]=nw;
        dfs(next);
    }
    return;
}
View Code

 T3

我和昨年一样没有长进【不还是多得了五分的】

剩下的都是TLE。

代码风格无论怎么说还是变了一些的。

这题就是个背包,完全=A=,但是我写得丑写不过……

昨年代码↓

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
ifstream fin("bird.in");
ofstream fout("bird.out");
bool jz[10002][1002]={0};//0表示可通行,1表示有管道 
int ss[2][10002]={0};//0表示点击后上升,1表示向下坠落
int DP[10002][1002]={0};//DP[i][j]表示在x坐标为i,y坐标为j下最小点击数 
bool gd[10002]={0};//记录每一x坐标是否有管道 
int Lx=0,Ly=0,Gds=0;
int main(void)
{
 fin>>Lx>>Ly>>Gds;
 for(int i=0;i<Lx;i++)fin>>ss[0][i]>>ss[1][i];
 int Gx=0,Up=0,Down=0;
 for(int i=1;i<=Gds;i++)
    {
     fin>>Gx>>Down>>Up;
     for(int j=0;j<=Down;j++)jz[Gx][j]=true;
     for(int j=Ly;j>=Up;j--)jz[Gx][j]=true;
     gd[Gx]=true;
    }
 memset(DP,127/2,sizeof(DP));
 for(int i=1;i<=Ly;i++)DP[0][i]=0;
 int ans=0x7fffffff,tgs=0,nxt=0;
 bool pd=false;
 for(int i=0;i<=Lx;i++)
    {
     ans=0x7fffffff;
     pd=false;
     for(int j=1;j<=Ly;j++)
        {
         if(DP[i][j]==1061109567)continue;
         if(jz[i][j])continue;
         pd=true;
         if(!jz[i+1][j-ss[1][i]]&&j-ss[1][i]>0)//如果不点击下一回合也不会死亡 
           {
            DP[i+1][j-ss[1][i]]=min(DP[i+1][j-ss[1][i]],DP[i][j]);
            if(DP[i+1][j-ss[1][i]]<ans)ans=DP[i+1][j-ss[1][i]];
           }
         for(int k=1;k<=Ly;k++)
            {
             nxt=k*ss[0][i];//点击k次后下一次上升的位置 
             if(nxt+j>Ly)nxt=Ly-j;
             if(jz[i+1][j+nxt])continue;
             DP[i+1][j+nxt]=min(DP[i+1][j+nxt],DP[i][j]+k);
             if(DP[i+1][j+nxt]<ans)ans=DP[i+1][j+nxt];
             if(nxt==Ly-j)break;
            }
        }
     if(!pd)break;
     if(gd[i])tgs++;
    }
 if(tgs==Gds)fout<<"1\n"<<ans;
 else fout<<"0\n"<<tgs;
 return 0;
}
View Code

今年的↓

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
int n=0,m=0,k=0,bef[10005]={0};
int up[10005]={0},down[10005]={0},dp[2][1005]={0};
bool check[10005][1003]={0};
const int INF=2139062143;
int main(void)
{
    freopen("bird.in","r",stdin);
    freopen("bird.out","w",stdout);
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++)scanf("%d%d",&up[i],&down[i]);
    int a=0,b=0,c=0;
    for(int i=1;i<=k;i++)
    {
        scanf("%d%d%d",&a,&b,&c);
        for(int j=0;j<=b;j++)check[a+1][j]=1;
        for(int j=c;j<=m;j++)check[a+1][j]=1;
        bef[a+1]++;
    }
    for(int i=1;i<=n;i++)bef[i]+=bef[i-1];
    memset(dp,0x7f,sizeof(dp));
    for(int i=1;i<=m;i++)dp[1][i]=0;
    int u=0,d=0,mark=0,ans=INF,loop=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(dp[i&1][j]!=INF&&!check[i][j])
            {
                mark=i;
                loop=max((m-j)/up[i]+1,1);
                for(int k=1;k<=loop;k++)
                {
                    u=min(m,j+up[i]*k);
                    if(!check[i+1][u])dp[(i+1)&1][u]=min(dp[(i+1)&1][u],dp[i&1][j]+k);
                    if(i==n)ans=min(ans,dp[(i+1)&1][u]);
                }
                d=max(0,j-down[i]);
                if(d==0)continue;
                if(!check[i+1][d])dp[(i+1)&1][d]=min(dp[(i+1)&1][d],dp[i&1][j]);
                if(i==n)ans=min(ans,dp[(i+1)&1][d]);
            }
        }
        for(int j=1;j<=m;j++)dp[i&1][j]=INF;
    }
    if(mark<n)
    {
        printf("0\n%d",bef[mark]);
        return 0;
    }
    printf("1\n%d",ans);
    return 0;
}
View Code
 posted on 2016-11-08 16:41  SakuLeaF  阅读(156)  评论(0编辑  收藏  举报