9.22-9.23考试总结

考场:把问题抽象成n个点的有向完全图上找到一条边权和不超过t的最长链。再加上把题意理解错了,完全爆炸,GG

正解,观察到最优状态下跳跃一定是时高度是连续递增或递减的(我是sb),拍完序后正反两边dp就可以了。

连这种水题都拿不到分,noip怎么混???!!!

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#define N 55
using namespace std;
int n,t,ans,dp[N][N];
struct zzh{
  int c,h;
}a[N];
bool cmp(zzh a,zzh b){
    return a.h<b.h;
}
int main(){
    freopen("meet.in","r",stdin);
    freopen("meet.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;++i)scanf("%d",&a[i].c);
    for(int i=1;i<=n;++i)scanf("%d",&a[i].h);
    scanf("%d",&t);
    sort(a+1,a+n+1,cmp);ans=1;
    memset(dp,0x3f,sizeof(dp));for(int i=1;i<=n;++i)dp[i][1]=a[i].c;
    for(int i=2;i<=n;++i)
      for(int j=2;j<=i;++j){
        for(int k=1;k<i;++k)
          dp[i][j]=min(dp[k][j-1]+a[i].c+a[i].h-a[k].h,dp[i][j]);
        if(dp[i][j]<=t)ans=max(ans,j);
    }
    memset(dp,0x3f,sizeof(dp));for(int i=1;i<=n;++i)dp[i][1]=a[i].c;
     for(int i=n-1;i>=1;--i)
      for(int j=1;j<=n-i+1;++j){
        for(int k=i+1;k<=n;++k)
          dp[i][j]=min(dp[k][j-1]+a[i].c+a[k].h-a[i].h,dp[i][j]);
        if(dp[i][j]<=t)ans=max(ans,j);
    }
    cout<<ans;
    fclose(stdin);
    fclose(stdout);
    return 0; 
} 

这题挺好玩的。

考场:观察到第一项为a[1]+a[2],第二项为a[1]+a[3]但后面无法确定&*%¥#¥%懒得往后想了,直接枚举第一个数,把后面暴力算出来,水了60.

正解,直接枚举a[2]+a[3]是几,可以把枚举范围缩小很多,加上剪枝可过。

我常数太大过不了,强行把我枚举范围缩到20过了。

#include<iostream>
#include<cstdio>
#include<set>
#include<algorithm>
#include<map>
#include<vector>
#define N 302
using namespace std;
int n,m,a[N*N],num[N],flag,tot,pre;
map<int,int>mp; 
set<int>se;
vector<int>vec[N];
int main(){
    freopen("city.in","r",stdin);
    freopen("city.out","w",stdout);
    scanf("%d",&n);m=n*(n-1)/2;
    for(int i=1;i<=m;++i)scanf("%d",&a[i]);
    sort(a+1,a+m+1);
    for(int i=3;i<=20;++i)
    if((a[1]+a[2]-a[i])%2==0){
        num[1]=(a[1]+a[2]-a[i])/2; if(num[1]==pre)continue;pre=num[1];
        num[2]=a[1]-num[1];flag=0;
        for(int j=2;j<=m;++j){
          if(se.find(a[j])==se.end())se.insert(a[j]);
          else mp[a[j]]++; 
        }
        for(int j=3;j<=n;++j){
            num[j]=*se.begin()-num[1];
            if(mp[num[j]+num[1]])mp[num[j]+num[1]]--;
            else se.erase(se.begin());
            for(int k=2;k<j;++k)
              if(se.find(num[k]+num[j])==se.end()){flag=1;break;}
              else {
              if(mp[num[j]+num[k]])mp[num[j]+num[k]]--;
               else se.erase(num[j]+num[k]);
            }
            if(flag)break;
        }
        if(!flag){
            tot++;
            for(int j=1;j<=n;++j)vec[j].push_back(num[j]);
        }
        while(se.size())se.erase(se.begin());
        mp.clear();
    }
    printf("%d\n",tot);
    for(int i=0;i<tot;++i){
      for(int j=1;j<=n;++j)
        printf("%d ",vec[j][i]);
      printf("\n");
   }
   fclose(stdin);
   fclose(stdout);
    return 0;
}

T3板子

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#define N 100002 
using namespace std;
int n,m,kuai[318][10002],a[N],f[318][103][103],mx,n1,be[N],n2,l,r,p,v,ans,ji[318][10002];
inline int rd(){
    int x=0;bool f=0;
    char c=getchar();
    while(!isdigit(c)){
      if(c=='-')f=1;
      c=getchar();
   }
    while(isdigit(c)){
        x=(x<<1)+(x<<3)+(c^48);
        c=getchar();
    }
    return f?-x:x;
}
int main(){
    freopen("light.in","r",stdin);
    freopen("light.out","w",stdout);
    n=rd();m=rd();
    for(int i=1;i<=n;++i)a[i]=rd(),mx=max(mx,a[i]);
    n1=sqrt(n);
    for(int i=1;i<=n;++i){
        be[i]=(i-1)/n1+1;
        kuai[be[i]][a[i]]++;
    }
    for(int i=1;i<=be[n];++i)
        for(int j=0;j<=mx;++j)
        ji[i][j]=kuai[i][j]+ji[i-1][j];
    n2=sqrt(mx);
    for(int i=1;i<=be[n];++i)
      for(int j=1;j<=n2;++j)
        for(int k=(i-1)*n1+1;k<=min(n,i*n1);++k)
          f[i][j][a[k]%j]++;
    while(m--){
        l=rd();r=rd();p=rd();v=rd();
        ans=0;
        if(v>p){
            printf("0\n");
            continue; 
        }
        if(p>mx){
            if(v>mx){
                printf("0\n");
                continue;
           }
           if(be[l]==be[r]){
               for(int i=l;i<=r;++i)if(a[i]==v)ans++;
           }
           else{
            for(int i=l;i<=min(be[l]*n1,n);++i)if(a[i]==v)ans++;
            for(int i=(be[r]-1)*n1+1;i<=r;++i)if(a[i]==v)ans++;
            for(int i=be[l]+1;i<be[r];++i)ans+=kuai[i][v]; 
           }
            printf("%d\n",ans);
        }
        else{
            if(be[l]==be[r]){
                for(int i=l;i<=r;++i)if(a[i]%p==v)ans++;
            }
            else{
            for(int i=l;i<=min(n,be[l]*n1);++i)if(a[i]%p==v)ans++;
            for(int i=(be[r]-1)*n1+1;i<=r;++i)if(a[i]%p==v)ans++; 
             if(p<=n2) for(int i=be[l]+1;i<be[r];++i)ans+=f[i][p][v];
             else if(be[r]-1>be[l])for(int j=v;j<=mx;j+=p)ans+=ji[be[r]-1][j]-ji[be[l]][j];
            }
            printf("%d\n",ans); 
        }
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

正反两边KMP,大水题

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 100002
using namespace std;
int  n,n1,n2,nex[N],nex2[N],j,tag,tag2;
char s[N],s1[N],s2[N],ss[N<<2];
inline void rd(){
    scanf("%s",ss+1);
    int ti=strlen(ss+1),i;
    for(i=1;ss[i]!=',';++i)s[++n]=ss[i];
    for(i=i+1;ss[i]!=',';++i)s1[++n1]=ss[i];
    for(i=i+1;i<=ti;++i)s2[++n2]=ss[i];
}
int main(){
    freopen("dis.in","r",stdin);
    freopen("dis.out","w",stdout);
    rd();
    for(int i=2;i<=n1;++i){
        while(j&&s1[i]!=s1[j+1])j=nex[j];
        if(s1[i]==s1[j+1])j++;
        nex[i]=j;
    }
    for(int i=1;i<=n2/2;++i)swap(s2[i],s2[n2-i+1]);
    j=0;
    for(int i=2;i<=n2;++i){
        while(j&&s2[i]!=s2[j+1])j=nex2[j];
        if(s2[i]==s2[j+1])j++;
        nex2[i]=j;
    }
    j=0;
    tag=tag2=0x3f3f3f3f;
    for(int i=1;i<=n;++i){
        while(j&&s[i]!=s1[j+1])j=nex[j];
        if(s[i]==s1[j+1])j++;
        if(j==n1){
            tag=i;
            break;
        }
    }
    for(int i=1;i<=n/2;++i)swap(s[i],s[n-i+1]);
    j=0;
    for(int i=1;i<=n;++i){
        while(j&&s[i]!=s2[j+1])j=nex2[j];
        if(s[i]==s2[j+1])j++;
        if(j==n2){
            tag2=i;
            break;
        }
    }
    int ans=n-tag2-tag;
    if(ans<0)printf("-1");
    else printf("%d\n",ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
} 

去重不加eps挂成10分,为啥不用sort去重!!!!

are  you silly B??!!!

#include<iostream>
#include<cstdio>
#include<map>
#include<cmath>
#include<algorithm>
#define N 1002
#define mm make_pair
using namespace std;
int xf,xs,yf,ys,r,n,ans,tot,top; 
double ling[N];
bool tag[N];
const double eps=1e-7;
struct sb{
    double x,y;
}ji[N];
struct zzh{
    double k,b;
}a[N];
bool cmp(sb a,sb b){
    if(fabs(a.x-b.x)>eps)return a.x<b.x;
    else return a.y<b.y; 
}
int main(){
    freopen("cake.in","r",stdin);
    freopen("cake.out","w",stdout);
    scanf("%d%d",&r,&n);ans=1;
    for(int i=1;i<=n;++i){
        scanf("%d%d%d%d",&xf,&yf,&xs,&ys);top=0;
        if(xs==xf){
            ling[++tot]=xs;tag[i]=1;
            for(int j=1;j<i;++j)if(!tag[j]){
               double x=xs,y=xs*a[j].k+a[j].b;
               if(x*x+y*y<=r*r)ji[++top].x=x,ji[top].y=y;
            }
            sort(ji+1,ji+top+1,cmp);
            for(int i=1;i<=top;++i)if(fabs(ji[i].x-ji[i-1].x)>eps||fabs(ji[i].y-ji[i].y)>eps)ans++;
        }
        else{
        a[i].k=(double)(ys-yf)/(double)(xs-xf);a[i].b=(double)ys-a[i].k*xs; 
        for(int j=1;j<i;++j)if(!tag[j]){
              double x=(a[j].b-a[i].b)/(a[i].k-a[j].k);
              double y=x*a[i].k+a[i].b;
              if(x*x+y*y<=r*r)ji[++top].x=x,ji[top].y=y;
        }
        for(int j=1;j<=tot;++j){
            double y=ling[j]*a[i].k+a[i].b,x=ling[j];
            if(x*x+y*y<=r*r)ji[++top].x=x,ji[top].y=y;
        }
        sort(ji+1,ji+top+1,cmp);
        for(int i=1;i<=top;++i)if(fabs(ji[i].x-ji[i-1].x)>eps||fabs(ji[i].y-ji[i].y)>eps)ans++;
        }
        ans++;
    }
    printf("%d\n",ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

垃圾丧病卡读入

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 1000002
using namespace std;
int n,k,a,b,head[N],tot,ta1[N],ta2[N],co[N],num[N],ans,st[N],top,h[N],now[N];
bool vis[N];
struct zzh{
    int n,to;
}e[N<<1];
inline void add(int u,int v){
    e[++tot].n=head[u];
    e[tot].to=v;
    head[u]=tot;
}
void dfs(){
   st[top=1]=1;memset(ta2,-0x3f,sizeof(ta2));
   for(int i=1;i<=n;++i)h[i]=head[i];
   while(top){
         int u=st[top],i;vis[u]=1;
         if(now[u]){
             int v=now[u];
             if(co[v]==1)ta1[u]=max(ta1[u],num[v]+1);//这里计算如果是未覆盖的情况,不算当前节点有多少未覆盖 
        else ta2[u]=max(ta2[u],num[v]-1);
        now[u]=0;
        }
         for(i=h[u];i;i=e[i].n)if(!vis[e[i].to]){
             int v=e[i].to;
             st[++top]=v;h[u]=e[i].n;now[u]=v;break;
      }
      if(!i){
              if(ta2[u]>=ta1[u]){//如果儿子都能覆盖 
      co[u]=2,num[u]=ta2[u];
      if(num[u]<0)co[u]=1,num[u]=0;
    }
    else {
        co[u]=1;num[u]=ta1[u];
        if(num[u]==k)co[u]=2,num[u]=k,ans++;
    }
    --top;
    }
   }
}
inline int rd(){
    int x=0;char c=getchar();
    while(!isdigit(c))c=getchar();
    while(isdigit(c)){
        x=(x<<1)+(x<<3)+(c^48);
        c=getchar();
    }
    return x;
}
int main(){
    freopen("coffee.in","r",stdin);
    freopen("coffee.out","w",stdout);
    n=rd();k=rd();
    for(int i=1;i<n;++i)a=rd(),b=rd(),add(a,b),add(b,a);
    dfs();
    if(co[1]==1)ans++;
    cout<<ans;
    fclose(stdin);
    fclose(stdout);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ZH-comld/p/9693164.html