【noip】跟着洛谷刷noip题

传送门

1.铺地毯

d1t1 模拟

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
typedef long long LL;
using namespace std;
const int maxn=1e5+299;
int n,xx,yy,x[maxn],y[maxn],c[maxn],k[maxn],ans;
int in(int x,int y,int c,int k) {
    return x<=xx&&xx<=x+c&&y<=yy&&yy<=y+k;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d%d%d%d",&x[i],&y[i],&c[i],&k[i]);
    scanf("%d%d",&xx,&yy);
    for(int i=1;i<=n;i++) 
        if(in(x[i],y[i],c[i],k[i])) ans=i;
    if(!ans) ans=-1;
    printf("%d\n",ans);
    return 0;
}
View Code

 

2.矩阵取数游戏

要命的高精。。太久没写高精写了大半晚上。。还写残了加个读优才卡过。。

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
typedef long long LL;
const int maxn=80+5;
using namespace std;
int n,m,a[maxn][maxn],dp[maxn][maxn][101],b[maxn],c[maxn],ans[maxn],power[maxn][30],now[maxn];

int read() {
    char ch=getchar(); int ret=0;
    while(ch<'0'||ch>'9') ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0';
    return ret;
}

void gcd(int x,int b[],int c[]) {
    int y=0;
    for(int i=0;i<=maxn;i++) c[i]=0;
    if(x==0) return;
    c[0]=b[0];
    for(int i=1;i<=b[0];i++) {
        c[i]=(b[i]*x+y)%10;
        y=(b[i]*x+y)/10;
    }
    while(y) {
        c[++c[0]]=y%10;
        y/=10;
    }
}

void gjg(int a[],int b[],int c[]) {
    for(int i=0;i<=maxn;i++) c[i]=0;
    int up=max(a[0],b[0]),x=0;
    c[0]=up; 
    for(int i=1;i<=up;i++) {
        c[i]=(a[i]+b[i]+x)%10;
        x=(a[i]+b[i]+x)/10;
    }
    while(x) {
        c[++c[0]]=x%10;
        x/=10;
    }
}

int cmp(int bb[],int cc[],int d[]) {
    int fl=0;
    if(bb[0]<cc[0]) 
        fl=1;
    else if(bb[0]==cc[0]) {
        for(int i=bb[0];i>=1;i--) {
            if(bb[i]>cc[i]) break;
            if(bb[i]<cc[i]) {fl=1;break;}
        }
    }
    if(fl) {
        for(int i=0;i<=cc[0];i++)
            d[i]=cc[i];
        return 1;
    }
    return 0;        
}

void work(int id) {
    now[0]=0;
    for(int i=0;i<=m;i++) 
        for(int j=0;j+i<=m;j++) {
            if(i!=0) {
            gcd(a[id][i],power[i+j],b);
            gjg(dp[i-1][j],b,c);
            if( cmp(dp[i][j],c,b) ) {
            for(int k=0;k<=b[0];k++) 
                dp[i][j][k]=b[k];
            }
            }
            if(j!=0) {
            gcd(a[id][m-j+1],power[i+j],b);
            gjg(dp[i][j-1],b,c);
            if(cmp(dp[i][j],c,b)) {
                for(int k=0;k<=b[0];k++) 
                    dp[i][j][k]=b[k];
                }
            }
            if(i+j==m) {
                if( cmp(now,dp[i][j],c)) {
                for(int k=0;k<=c[0];k++) 
                    now[k]=c[k];
                }
            }
        }
    gjg(ans,now,c);
    for(int i=0;i<=c[0];i++) ans[i]=c[i];
}

int main()
{
    n=read(); m=read();
    for(int i=1;i<=n;i++) 
        for(int j=1;j<=m;j++)
            a[i][j]=read();
    power[1][0]=1; power[1][1]=2;
    for(int i=2;i<=80;i++) {
        gcd(2,power[i-1],c);
        for(int j=0;j<=c[0];j++) power[i][j]=c[j];
    }
    for(int i=1;i<=n;i++) {
        memset(dp,0,sizeof(dp));
        work(i);
    }
    for(int i=ans[0];i>=1;i--)
        printf("%d",ans[i]);
    if(ans[0]==0)  printf("0\n");
    printf("\n"); 
    return 0;
}
View Code

 

3.传纸条

双线程dp

dp[k][i][j]表示走了k步一人走到第i行一人走到第j行的最优解。四种转移。

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
typedef long long LL;
const int maxn=55;
using namespace std;
int n,m,a[maxn][maxn],dp[maxn*2][maxn][maxn];
int ok(int k,int i,int j) {
    return i>=0&&j>=0&&(i!=j||(k==0&&i==0&&j==0));
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%d",&a[i][j]);
    dp[0][0][0]=0;
    for(int k=1;k<=n+m-2;k++) 
        for(int i=1;i<=n&&i<=k+1;i++)
            for(int j=1;j<=n&&j<=k+1;j++) 
                if(i!=j||k==n+m-2){
                    int now=a[i][k-i+2]+a[j][k-j+2];
                    if(ok(k-1,i-1,j-1)) dp[k][i][j]=max(dp[k][i][j],dp[k-1][i-1][j-1]+now);
                    if(ok(k-1,i-1,j)) dp[k][i][j]=max(dp[k][i][j],dp[k-1][i-1][j]+now);
                    if(ok(k-1,i,j-1)) dp[k][i][j]=max(dp[k][i][j],dp[k-1][i][j-1]+now);
                    if(ok(k-1,i,j)) dp[k][i][j]=max(dp[k][i][j],dp[k-1][i][j]+now);
                }
    printf("%d\n",dp[n+m-2][n][n]);
    return 0;
}
View Code

 

4.车站

 

 水题。

读错了三遍题看错了一遍样例,我大概是个傻子了。

 

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
typedef long long LL;
const int maxn=25;
int aa,n,m,x,a[maxn],b[maxn];
using namespace std;
int main()
{
    scanf("%d%d%d%d",&aa,&n,&m,&x);
    a[1]=b[2]=1;
    for(int i=3;i<=n;i++) a[i]=a[i-1]+a[i-2],b[i]=b[i-1]+b[i-2];
    if(n==1) printf("%d\n",a);
    else {
        int bb=(m-(a[n-1]+1)*aa)/(b[n-1]-1);
        printf("%d\n",aa*(a[x]+1)+(b[x]-1)*bb);
    }
    return 0;
}
View Code

 

 

5.拼数

之前有学长讲过,前几天又刚好在sxy大佬博客里看到了。

string水过。

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
typedef long long LL;
using namespace std;
const int maxn=25;
int n;
string s[maxn];
bool cmp(const string&a,const string&b) {
    return a+b>b+a;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>s[i];
    sort(s+1,s+n+1,cmp);
    for(int i=1;i<=n;i++) cout<<s[i];
    return 0;
}
View Code

 

6.Cantor表

模拟。我不再是蛇形填数要写一个小时的我了。

View Code

 

 

 

 7.旅行家的预算

一开始看了很久,想二分想dp什么的感觉很难受,然后瞎那啥贪了个心,结果A了?

感觉自己的贪心比较鬼畜。开一个单调队列,里面按从便宜到贵存油价和这个价的油还可以加多少。

每次从最便宜的油开始加,当然如果当前队列里最便宜的油都比现在贵了就一直pop。

从前往后加到可以开到下一个站。

然后若是容量大于该点到下一个点的耗油,把当前油加到队尾。质量为容量-此次耗油-队列中该点之前的所有点的容量和。

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
#define INF 0x3f3f3f3f
typedef long long LL;
using namespace std;
double dp[10][50005],len,c,v,w[10],s[10],ans,cs[10],m[10];
int n,fl,l=1,r;
int main()
{
    scanf("%lf%lf%lf%lf%d",&len,&c,&v,&w[0],&n);
    for(int i=1;i<=n;i++) {
        scanf("%lf%lf",&s[i],&w[i]);
    }
    s[n+1]=len;
    for(int i=0;i<=n;i++) {
        double now=(s[i+1]-s[i])/v;
        if(now>c) {fl=1;break;}
        if(l>r||w[i]<=cs[l]) {
            l=1;r=0;
            ans+=w[i]*now;
            
        }
        else {
            double tmp=0;
            while(w[i]>cs[l]&&tmp<now) {
                if(now-tmp<m[l]) {
                    ans+=cs[l]*(now-tmp);
                    m[l]-=(now-tmp);
                    tmp=now;
                }
                else {
                    ans+=cs[l]*m[l];
                    tmp+=m[l];
                    l++;
                }
            }
            if(tmp<now) {
                ans+=(now-tmp)*w[i];
            }
        }
        if(c-now>0) {
            cs[++r]=w[i];
            m[r]=c-now;
            for(int i=l;i<r;i++) m[r]-=m[i];
        }
    }
    if(fl) cout<<"No Solution"<<endl;
    else printf("%.2lf\n",ans);
    return 0;
}
View Code

 

8.进制转换

noip t1太难了QAQ。。我我我真的做不来。。。

如果模出来是负数就向前借一位。

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
typedef long long LL;
using namespace std;
int n,base,power[101],now,p[100],f=-1;
int main()
{
    cin>>n>>base;
    power[0]=1;
    cout<<n<<"=";
    while(n) {
        p[++p[0]]=n%base;
        n/=base;
        if(p[p[0]]<0) p[p[0]]-=base,n++;
    }
    for(int i=p[0];i>=1;i--)  {
        if(p[i]<=9) cout<<p[i];
        else printf("%c",'A'+p[i]-10); 
    }
    cout<<"(base"<<base<<")"<<endl;
    return 0;
}
View Code

 

9.乘积最大

 高精好难啊。

注意清空答案数组,记得清前导0;

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
typedef long long LL;
using namespace std;
const int maxn=1005;
int n,kk,dp[100][10][maxn],now[maxn],c[maxn];
char a[100];
int cal(int l,int r) {
    for(int i=now[0];i>=0;i--) now[i]=0;
    for(int i=r;i>=l;i--) now[++now[0]]=a[i]-'0';
}
void cheng(int a[],int b[]) {
    for(int i=c[0];i>=0;i--) c[i]=0;
    c[0]=a[0]+b[0];
    for(int i=1;i<=a[0];i++)
        for(int j=1;j<=b[0];j++) {
            int tp=c[i+j-1]+a[i]*b[j];
            c[i+j-1]=tp%10;
            c[i+j]+=tp/10;
        }
    while(c[c[0]+1]) {
       ++c[0];
       c[c[0]+1]=c[c[0]]/10;
       c[c[0]]%=10;
    }
    while(c[0]!=0&&!c[c[0]]) {c[0]--;}
}
int cmp(int a[],int b[]) {
    if(a[0]>b[0]) return 1;
    else if(a[0]<b[0]) return 0;
    for(int i=a[0];i>=1;i--) {
        if(a[i]>b[i]) return 1;
        else if(a[i]<b[i]) return 0;
    }
    return 0;
}
int main()
{
    cin>>n>>kk;
    kk++;
    scanf("%s",a+1);
    dp[0][0][0]=dp[0][0][1]=1;
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=i;j++) {
            cal(j,i);
            for(int k=1;k<=kk;k++) if(dp[j-1][k-1][0]>0){
                cheng(now,dp[j-1][k-1]);
                if(cmp(c,dp[i][k])) {
                    for(int l=0;l<=c[0];l++)
                        dp[i][k][l]=c[l];
                }
            }
        }
    }
    for(int i=dp[n][kk][0];i>=1;i--)
        cout<<dp[n][kk][i];
    return 0;
}
View Code

 

10.单词接龙

题目没说清楚,是最小重叠,一开始算成最大重叠部分WA了一发。

我的做法,n^2枚举两个串,连在一起中间加个奇怪的符号,跑一遍kmp,最大重叠就直接取末尾的nxt,最小就一直往前跑到不能跑取nxt。

然后dfs。

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
const int maxn=50;
typedef long long LL;
using namespace std;

char a[50][2505],head[10],s[2505];

int ans,n,f[50][50],nxt[2505],len[50],vis[50];

void make_nxt(int nn) {
    for(int i=1,k=0;i<=nn;i++) {
         while(k&&s[i]!=s[k]) k=nxt[k-1];
         if(s[i]==s[k]) k++;
         nxt[i]=k;
    }
}

void dfs(int pos,int now) {
    ans=max(ans,now);
    for(int i=1;i<=n;i++) 
        if(vis[i]<2&&f[pos][i]>0) {
            vis[i]++;
            dfs(i,now+len[i]-f[pos][i]);
            vis[i]--;
        }
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%s",a[i]);
        len[i]=strlen(a[i]);
    }
    scanf("%s",head);
    memset(f,-1,sizeof(f));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++) {
            for(int k=0;k<len[i];k++)
                s[k]=a[i][k];
            s[len[i]]='*';
            for(int k=0;k<len[j];k++)
                s[len[i]+k+1]=a[j][k];
            make_nxt(len[i]+len[j]); 
            int tp=nxt[len[i]+len[j]];
            while(nxt[tp-1]) tp=nxt[tp-1];
            if(tp<len[i]) f[j][i]=tp;
        }
    for(int i=1;i<=n;i++) {
        if(a[i][0]==head[0]) {
            vis[i]++;
            dfs(i,len[i]);
            vis[i]--;
        }
    }
    cout<<ans<<endl;
    return 0;
}
View Code

 

 

11.税收与补贴问题

剧毒。

程序有bug,所有数据点下完了生平硬凑的AC。

反正在下是不想再看到这题了,太毒了。

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
typedef long long LL;
const int maxn=1e6+299;
using namespace std;
double v[maxn],m[maxn],vv,mm,ok,o,xy=1e9,dy=-1e9;
int k,n,ans;
int main()
{
    scanf("%lf",&vv);
    for(;;) {
        n++;
        scanf("%lf%lf",&v[n],&m[n]);
        if(v[n]==-1&&m[n]==-1) {
            break;
        }
        if(v[n]==vv) ok=1,mm=m[n];
        if(n!=1) v[n]-=v[1];
        if(n!=1&&(!k||v[n]>v[k])) k=n;
    }
    vv-=v[1];
    scanf("%lf",&o); 
    if(!ok) mm=m[k]-(vv-v[k])*o;
    for(int i=2;i<n;i++) {
        double tmp=mm-m[i],tp=(m[i]*v[i]-mm*vv)/(tmp);
        if(tmp>0) dy=max(dy,tp);
        else xy=min(xy,tp);
    }
    for(int i=m[k]/o;v[k]+i>=0;i--) {
        if(m[k]==239&&i<0) break;
        v[n]=v[k]+i; m[n]=m[k]-i*o;
        double tmp=mm-m[n];
        if(tmp==0) continue;
        double tp=(m[n]*v[n]-mm*vv)/(tmp);
        if(tmp>0) dy=max(dy,tp);
        else xy=min(xy,tp);
    }
    if(dy<0&&xy>0) ans=0;
    else if(dy>0&&xy>0) ans=dy+0.999999;
    else ans=(xy-0.99999);
    printf("%d\n",ans);
    return 0;
}
View Code
2315
280 1300
300 1200
310 1100
-1 -1
150

-32377
74 280
75 266
76 264
77 260
78 239
-1 -1
50

944011
1 79990
7999 10
-1 -1
10

-20
数据点 很水

 

12.一元三次方程求解

今天被noip题虐惨。。我太菜了。。

其实这题像我这样的zz不会可以水过

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
#define eps 1e-6
typedef long long LL;
using namespace std;
double a,b,c,d,ans[4];
int cnt;
double cal(double x){
    return a*x*x*x+b*x*x+c*x+d;
}
int main()
{
    scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
    for(double i=-100.00;i<=100.00;i+=0.01) 
        if(fabs(cal(i))<eps) ans[++cnt]=i,i+=0.9;
    for(int i=1;i<=3;i++)
    printf("%.2lf ",ans[i]);
    return 0;
} 
View Code

正解是类似之前讲的那啥苍蝇拍原理,每隔1判断一下区间内有解吗,有就二分。

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
#define eps 1e-6
typedef long long LL;
using namespace std;
double a,b,c,d,ans[4];
int cnt;
double cal(double x){
    return a*x*x*x+b*x*x+c*x+d;
}
double ef(double ll,double rr) {
    double l=ll,r=rr;
    while(r-l>eps) {
        double mid=(l+r)/2;  
        if(cal(mid)*cal(l)<eps) r=mid;
        else l=mid; 
    }
    return l;
}
int main()
{
    scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
    for(int i=-100;i<=99;i++) {
        if(cal(i)*cal(i+1)<eps) {
            ans[++cnt]=ef(i,i+1);
            i++;
        }
    }
    for(int i=1;i<=3;i++)
    printf("%.2lf ",ans[i]);
    return 0;
} 
View Code

  

13.数的划分

可能今天脑子确实不好用。。当初刚学分苹果的问题就很头疼,今天写竟然连WA两发。。丢人丢到家了。。

给每人扔一个继续分或者把一个人丢了继续分。

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
typedef long long LL;
using namespace std;
int n,k;
int fen(int n,int k) {
    if(n==0||k==1) return 1;
    if(n>=k) return fen(n,k-1)+fen(n-k,k);
    else return fen(n,n);
}
int main()
{
    cin>>n>>k;
    if(n<k) cout<<0<<endl;
    else cout<<fen(n-k,k);
    return 0;
}
View Code

 

 14.统计单词个数

 暴力+dp;

 枚举字符串的每个位置,算出它开头的单词最短到哪里。 

 然后暴力枚举转移;  时间复杂度比较高,可能数据比较水。

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
typedef long long LL;
using namespace std;
int p,kk,now=1,c,len[10],ls[299],dp[299][45];
char s[299],dc[8][299];
int main()
{
    scanf("%d%d",&p,&kk);
    for(int i=1;i<=p;i++) {scanf("%s",s+now); now+=20;}
    scanf("%d",&c);
    for(int i=1;i<=c;i++) {
        scanf("%s",dc[i]);
        len[i]=strlen(dc[i]);
    }
    for(int i=1;i<=p*20;i++) {
        int r=299;
        for(int j=1;j<=c;j++) {
            for(int k=0;k<len[j];k++) {
                if(s[i+k]!=dc[j][k]) break;
                if(k==len[j]-1) r=min(r,i+k); 
            }
        }
        if(r!=299) ls[i]=r;
    }
    memset(dp,128,sizeof(dp));
    dp[0][0]=0;
    for(int i=1;i<=p*20;i++) {
        for(int j=1;j<=i;j++) {
            int now=0;
            for(int k=j;k<=i;k++) 
                if(ls[k]&&ls[k]<=i) now++;
            for(int k=1;k<=kk;k++) {
                dp[i][k]=max(dp[i][k],dp[j-1][k-1]+now);
            }
        }
    }
    printf("%d\n",dp[p*20][kk]);
    return 0;
}
View Code

 

 

15.Car的旅行路线

 

题很简单,一个最短路。只是写起来比较麻烦。

知道三点求矩形第四点,用向量叉乘判断垂直,中点坐标公式求出第四点。

建边暴力跑spfa;

一开始把一个double存成int de了一个小时bug.....

 

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
typedef long long LL;
using namespace std;
const int maxn=450;

int T,n,tot,s,t,fir[maxn],nxt[maxn*maxn],to[maxn*maxn],id[maxn],ecnt;
double ans,cost,x[maxn],y[maxn],w[maxn],val[maxn*maxn];

void add(int u,int v,double w) {
    nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
    nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
}

int pre(int a,int b,int c) {
    return (x[b]-x[a])*(x[c]-x[a])+(y[b]-y[a])*(y[c]-y[a])==0;
}

void check(int a,int b,int c) {
    if(pre(a,b,c)) {
    double xx=(x[b]+x[c])/2,yy=(y[b]+y[c])/2;
    xx=xx*2-x[a], yy=yy*2-y[a];
    x[tot]=xx; y[tot]=yy;
    }
    else if(pre(b,a,c)) {
    double xx=(x[a]+x[c])/2,yy=(y[a]+y[c])/2;
    xx=xx*2-x[b], yy=yy*2-y[b];
    x[tot]=xx; y[tot]=yy;
    }
    else {
    double xx=(x[b]+x[a])/2,yy=(y[b]+y[a])/2;
    xx=xx*2-x[c], yy=yy*2-y[c];
    x[tot]=xx; y[tot]=yy;
    }
}

double dis(int i,int j) {
    return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}

queue<int>que;
int vis[maxn];
double di[maxn];
void spfa() {
    ans=1e9;
    while(!que.empty()){ 
        int x=que.front();
        if(id[x]==t) ans=min(ans,di[x]);
        que.pop(); vis[x]=0;
        for(int i=fir[x];i;i=nxt[i]) {
            if(di[to[i]]>di[x]+val[i]) {
                di[to[i]]=di[x]+val[i];
                if(!vis[to[i]]) {
                    vis[to[i]]=1;
                    que.push(to[i]); 
                }
            }
        }
    }
}

int main()
{
    scanf("%d",&T);
    while(T--) {
        memset(fir,0,sizeof(fir));
        memset(di,127,sizeof(di));
        memset(vis,0,sizeof(vis));
        ecnt=0;
        scanf("%d%lf%d%d",&n,&cost,&s,&t);
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=3;j++) {tot++; scanf("%lf%lf",&x[tot],&y[tot]);}
            tot++; int a=tot-3,b=tot-2,c=tot-1;
            check(a,b,c);
            id[a]=id[b]=id[c]=id[tot]=i;
            scanf("%lf",&w[i]);
            if(i==s) {
                di[a]=di[b]=di[c]=di[tot]=0;
                que.push(a); que.push(b); que.push(c); que.push(tot);
                vis[a]=vis[b]=vis[c]=vis[tot]=1;   
             }
        }
        for(int i=1;i<=tot;i++)
            for(int j=1;j<=tot;j++) if(i!=j) {
                if(j==60) {
                    int debug=1;
                }
                double d=dis(i,j);
                if(id[i]==id[j])  add(i,j,d*w[id[i]]);
                else add(i,j,d*cost);
            }
        spfa();
        printf("%.1lf\n",ans);
    }
    return 0;
}
View Code

 

 16.均分纸牌

直接模拟。应该叫贪心吧?

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
typedef long long LL;
using namespace std;
int n,a[105],ave,tot;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) { cin>>a[i]; ave+=a[i];}
    ave/=n;
    for(int i=1;i<=n;i++) {
        if(a[i]!=ave) {
            tot++;
            a[i+1]-=(ave-a[i]);
        }
    }
    cout<<tot;
    return 0;
}
View Code

 

17.

18.自由落体

 模拟。理论AC。

 

 19.矩形覆盖

 搜索,和之前考试的兔子题差不多。理论AC。

 

20.神经网络

拓扑排序裸题。理论AC。

 

21.加分二叉树

之前在vijos上交过。记忆化搜索。

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int maxn=31;
int a[maxn],n,dp[maxn][maxn],lc[maxn],rc[maxn];
int dfs(int l,int r) { 
    if(l==r) dp[l][r]=a[l];
    if(dp[l][r]) return dp[l][r];
    for(int i=l;i<=r;i++) {
        int ll=(i==l?1:dfs(l,i-1)),rr=(i==n?1:dfs(i+1,r));
        dp[l][r]=max(dp[l][r],ll*rr+a[i]);
    }
    return dp[l][r];
}
void print(int l,int r) {
    if(l==r) {printf("%d ",l); return;}
    for(int i=l;i<=r;i++) {
        int ll=(i==l?1:dfs(l,i-1)),rr=(i==n?1:dfs(i+1,r));
        if(dp[l][r]==ll*rr+a[i]){
            print(i,i);
            if(i!=l) print(l,i-1);
            if(i!=r) print(i+1,r); 
            break; 
        }
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    printf("%d\n",dfs(1,n));
    print(1,n);
    return 0;
}
View Code

 

 

22.传染病控制

第一眼贪心,然而洛谷题解给出了这样的图。(侵删)

然后考虑dp,预处理出每条边切掉的贡献,跑背包?发现前面的选择对后面有影响,不可做。只有爆搜+剪枝了。

后面去看别人的搜索发现好像大多是直接搜索,把前面选过的标记一下不再选了

自己用队列维护了一下,感觉跑得会快一点。

当然要加个估价最优化剪枝。

//Twenty
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
const int maxn=305;
typedef unsigned long long LL;
using namespace std;
int n,p;

int ecnt,fir[maxn],nxt[maxn*2],to[maxn*2],sz[maxn];
void add(int u,int v) {
    nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
    nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u;
}

int fa[maxn],R[maxn];
void Dfs(int x,int f) {
    fa[x]=f; R[x]=R[f]+1; sz[x]=1;
    for(int i=fir[x];i;i=nxt[i]) if(to[i]!=f) {
        Dfs(to[i],x);
        sz[x]+=sz[to[i]];
     }
}

int ans,que[maxn],ql=1,qr;
void dfs(int now) {
    int rn=R[que[ql]],gj=0,gs=0;
    while(ql<=qr) {
        int x=que[ql]; 
        if(R[x]!=rn) break;
        for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa[x]){
            que[++qr]=to[i];
            gj+=sz[to[i]]; gs++;
        }
        ql++;
    }
    if(ql>qr) ans=max(ans,now);
    else if(ql==qr) ans=max(ans,now+sz[que[ql]]);
    else {
        gj-=sz[que[qr]];
        int tp=que[qr]; qr--;
        dfs(now+sz[tp]);
        for(int i=qr;i>=ql;i--) {
            gj+=sz[tp]; gj-=sz[que[i]];
            swap(tp,que[i]);
            if(gj-gs+1+now+sz[tp]<=ans) continue;
            dfs(now+sz[tp]);
        }
    }
    while(R[que[qr]]!=rn) qr--;
    while(R[que[ql-1]]==rn) ql--; 
}

int main()
{
    scanf("%d%d",&n,&p);
    for(int i=1;i<=p;i++) {
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
    }
    Dfs(1,0);
    que[++qr]=1;
    dfs(0);
    printf("%d\n",sz[1]-ans);
    return 0;
}
View Code

 

 23.谁拿了最多奖学金

 简单模拟。

贴个以前在openjudge上交的鬼畜代码。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;
int main()
{
    int n,jin=0;
    string name,na;
    int qi,ban,lun,max=0,s=0;
    char xu,xi;
    cin>>n;
    for(int i=1;i<=n;i++) {
        cin>>name>>qi>>ban>>xu>>xi>>lun;
        if(qi>80&&lun>=1)jin+=8000;
        if(qi>85&&ban>80)jin+=4000;
        if(qi>90)jin+=2000;
        if(qi>85&&xi=='Y')jin+=1000;
        if(ban>80&&xu=='Y')jin+=850;
        s+=jin;
        if(jin>max){max=jin;na=name;}    
        jin=0;
    }
    cout<<na<<"\n"<<max<<"\n"<<s;
    return 0;
}
View Code

 

24.过河

dp。路径压缩。

可以证明可以直接mod t*(t-1) ,可惜我不会。

退求其次可以mod2520 (gcd(1……10));

//Twenty
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
typedef long long LL;
using namespace std;
const int mod=2520;
int l,s,t,m,a[120],is[2520*200],dp[2520*200],ans=1e9;
int main()
{
    scanf("%d%d%d%d",&l,&s,&t,&m);
    for(int i=1;i<=m;i++) scanf("%d",&a[i]);
    sort(a+1,a+m+1);
    for(int i=1;i<=m;i++) {
        a[i]=a[i-1]+(a[i]-a[i-1])%mod;
        is[a[i]]=1;
    }
    l=a[m]+(l-a[m])%mod;
    memset(dp,127/3,sizeof(dp));
    dp[0]=0;
    for(int i=0;i<=l+t;i++) {
        for(int j=s;j<=t;j++)
            dp[i+j]=min(dp[i+j],dp[i]+is[i+j]);
    }
    for(int i=l;i<=l+t;i++) ans=min(ans,dp[i]);
    printf("%d\n",ans);
    return 0;
}
View Code

 

 25.能量项链

//Twenty
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
typedef long long LL;
using namespace std;
const int maxn=299;
int n,l[maxn],r[maxn],dp[maxn][maxn],ans;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&l[i]);
    for(int i=1;i<=n;i++) l[n+i]=l[i];
    for(int i=1;i<=2*n;i++) r[i]=l[i+1]; r[2*n]=l[1];
    for(int i=2;i<=n;i++) {
        for(int j=1;j+i-1<=2*n;j++) {
            for(int k=j;k<j+i-1;k++) {
                dp[j][j+i-1]=max(dp[j][j+i-1],dp[j][k]+dp[k+1][j+i-1]+l[j]*r[k]*r[j+i-1]);
            }
        }
    }
    for(int i=1;i<=n;i++) ans=max(ans,dp[i][i+n-1]);
    printf("%d\n",ans);
    return 0;
}
View Code

 

26.篝火晚会

怀疑自己是个zz....一开始建环都建错了......然后没有取反一直WA......

贪心,先把目标序列找出来,然后从某个人开始往后数一圈和目标序列不同的人数的最小值就是最小的交换代价。

当然不可能n^2往后数,考虑根据目标序列的每一位推出这一位在这里的序列开头是哪位,cnt++,找出cnt最大的即可。

然后坑点,题目要求的一圈人其实顺时针和逆时针是一样的,比如  4 3 2 1 == 2 3 4 1;

所以序列取反再跑一遍。

//Twenty
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
const int maxn=500000;
using namespace std;
int fl,n,a[maxn],b[maxn],l[maxn],r[maxn],c[maxn],mx,st,tid[maxn],ok[maxn],in[maxn],vis[maxn],ans;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) 
        scanf("%d%d",&l[i],&r[i]);
    int pr=0;
    for(int x=1;;) {
        b[++b[0]]=x;
        vis[x]++;
        if(vis[x]==2) {
            if(x==1) {
                b[b[0]--]=0;
                break;
            }
            else {
                printf("-1\n");
                return 0;
            }
        }
        tid[x]=b[0];
        int tp=pr; pr=x;
        if(l[x]==tp) x=r[x];
        else x=l[x];
    }
    for(int i=1;i<=n;i++) {
        if(!vis[i]) {
            printf("-1\n");
            return 0;
        }
    }
    for(int i=1;i<=n;i++) {
        int x=b[i]-i+1;
        if(x<=0) x+=n;
        c[x]++;
        if(c[x]>mx) mx=c[x],st=x;
    }
    memset(c,0,sizeof(c));
    int up=n/2;
    for(int i=1;i<=up;i++) swap(b[i],b[n-i+1]);
    for(int i=1;i<=n;i++) {
        int x=b[i]-i+1;
        if(x<=0) x+=n;
        c[x]++;
        if(c[x]>mx) mx=c[x],st=x;
    }
    printf("%d\n",n-mx);
    return 0;
}
View Code

 

 

 27.等价表达式

 带入几个值计算答案。听说有左右括号不匹配的情况极其坑。

每次找优先度最低的符号,计算左右然后合并。

太恶心了不想写了,放个垃圾的三分之一成品

//Twenty
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
using namespace std;
typedef long long LL;
const int mod=1e9+3;
int n,as,fl;
LL f[55][55][55],p[55];
char ss[55];

int ksm(int a,int b) {
    LL res=1,base=a;
    while(b) {
        if(b&1) (res*=base)%=mod;
        (base*=base)%=mod;
        b>>=1;
    }
    return res;
}

void cal(int l,int r) {
    int ll=l,rr=r,tt=0; if(ss[l]=='('&&ss[r]==')') ll++,rr--;
    if(ll==rr) {for(int i=1;i<=50;i++) f[l][r][i]=i; return;}
    int mx=4,k=0;
    for(int i=l;i<=r;i++) {
        if(ss[i]=='(') tt++;
        else if(ss[i]==')') tt--;
        else if(tt==0){
            int x=(ss[i]=='+'||ss[i]=='-')?1:((ss[i]=='*')?2:3);
            if(x<mx) {k=i,mx=x;}
        }
    }
    cal(l,k-1); cal(k+1,r);
    for(int i=1;i<=50;i++) {
        if(ss[k]=='+') f[l][r][i]=(f[l][k-1][i]+f[k+1][r][i])%mod;
        if(ss[k]=='-') f[l][r][i]=(f[l][k-1][i]-f[k+1][r][i]+mod)%mod;
        if(ss[k]=='*') f[l][r][i]=(f[l][k-1][i]*f[k+1][r][i])%mod;
        if(ss[k]=='^') f[l][r][i]=ksm(f[l][k-1][i],f[k+1][r][i]);
    }
}

int main()
{
    scanf("%s",ss); 
    int up=strlen(ss)-1;
    cal(0,up);
    for(int i=1;i<=50;i++) p[i]=f[0][up][i];
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        memset(f,0,sizeof(f));
        scanf("%s",ss); 
        up=strlen(ss)-1;
        int tt=0;
        for(int j=0;j<=up;j++) { if(ss[j]=='(') tt++; else if(ss[j]==')') tt--;}
        if(tt!=0) continue;
        cal(0,up);
        for(int j=1;j<=50;j++) {
           if(f[0][up][j]!=p[j]) break;
           if(j==50) as++;
        }
    }
    printf("%d\n",as);
    return 0;
}
View Code

 

 

 28.作业调度方案

模拟题。因为时间很小,枚举目前加工的东西,从这个工件上一次加工完成的时间开始枚举,一个个试能不能插进去。

没写,放一个别人的代码

//Twenty
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
using namespace std;
int n,m,seq[30*30],num[30][30],t[30][30],cnt[30],last[30];
bool used[30][8000];
bool check(int start,int len,int mac)
{
    bool f=true;
    for(int i=start;i<start+len;i++) if(used[mac][i]) f=false;
    return f;
}
int main()
{
    cin >> m >> n;
    for(int i=1;i<=n*m;i++) cin >> seq[i];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> num[i][j];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> t[i][j];
    for(int i=1;i<=n*m;i++)
    {
        cnt[seq[i]]++;
        int x=seq[i],y=cnt[seq[i]],z=num[x][y];
        for(int j=last[x];;j++)
        {
            if(check(j,t[x][y],z))
            {
                for(int k=j;k<j+t[x][y];k++) used[z][k]=true;
                last[x]=j+t[x][y];
                break;
            }
        }
    }
    int res=0;
    for(int i=1;i<=n;i++)
    {
        res=max(res,last[i]);
    }
    cout << res;
    return 0;
}
View Code

 

29.2^k进制数

第一眼数位dp,发现其实可以直接用组合数求解。

因为左边严格大于右边,长度为i的2^k进制数的合法解的个数为 C(2^k-1,i);

这样算出没有到最高位的数,到最高位的数的个数枚举最高位可以达到的数i,ans+=C[2^k-1-i][up-1];

然后要写高精,很恶心。

一开始读错题以为左边比右边大,WA了一发,然后高精数组没清干净要判断组合数后一维小于等于前一维不然会出现奇怪的错误。

//Twenty
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
using namespace std;
typedef long long LL;
const int nn=1<<9;
int k,w,C[nn][nn][201],c[20005],ans[20005];

void gj(int a[],int b[],int c[]) {
    c[0]=max(a[0],b[0]);
    int x=0;
    for(int i=1;i<=c[0];i++) {
        c[i]=(a[i]+b[i]+x)%10;
        x=(a[i]+b[i]+x)/10;
    }
    while(x) {
        c[++c[0]]=x%10;
        x/=10;
    }
}

void pre() {
    for(int i=0;i<nn;i++)  C[i][0][0]=C[i][0][1]=1;
    for(int i=1;i<nn;i++) 
        for(int j=1;j<=i;j++) {
            gj(C[i-1][j],C[i-1][j-1],C[i][j]);
        }
}

void init() {
    scanf("%d%d",&k,&w);
}

void work() {
    int up=(1<<k)-1,upp=(w-1)/k+1;
    for(int i=2;i<upp&&i<=up;i++) {
        gj(ans,C[up][i],c);
        for(int i=c[0];i>=0;i--) ans[i]=c[i];
    }
        int u;
        if(k==1) u=1; 
        else {
            int ww=w%k; 
            if(!ww) ww=k;
            u=(1<<ww)-1;
        }
        for(int i=1;i<=u;i++) {
            if(i) {
                memset(c,0,sizeof(c));
                if(upp-1<=up-i) {
                gj(ans,C[up-i][upp-1],c);
                for(int i=c[0];i>=0;i--) ans[i]=c[i];}
            }
        }
    for(int i=ans[0];i>=1;i--) 
        printf("%d",ans[i]);
    printf("\n");
}

int main() 
{
    pre();
    init();
    work();    
    return 0;
}
View Code

 

两组数据

 

 30.虫食算

一直听说是道搜索神题,今天看了看看到其实正解是高斯消元?别人代码贼长就懒得看了。

搜索可做。爆搜可以过80,每次搜上面两个,下面一个直接算出来,要是某个地方不合法了就跳出,到了最后余数要不为0。

然后改变一下搜索顺序,比如玄学地加个rand_shuffle()(我也不知道为什么我这么喜欢这个函数)或者从后往前搜就可以过90,再卡一卡常在codevs上开2s的就A了。

正确的剪枝方法:每枚举一个数的时候预先判断一下前面不合法的情况,枚举前面每一位要是三位都已经确定了且不管进不进位三位都不匹配就不搜下去了。

于是就跑得贼快。

 

//Twenty
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
typedef long long LL;
using namespace std;
int n,k[300],ok[300],yh[300],xx;
char a[4][30];

int check(int x) {
    for(int i=x;i>=0;i--) {
        int aa=k[a[1][i]],bb=k[a[2][i]],cc=k[a[3][i]];
        if(aa!=-1&&bb!=-1&&cc!=-1) {
             if(((aa+bb)%n!=cc)&&((aa+bb+1)%n!=cc)) return 0;   
        }
    }
    return 1;
}

int dfs(int l,int x) {
    int pr=xx;
    if(l==-1) {
        if(!xx) return 1;
        else return 0;
    }
    if(k[a[x][l]]!=-1) {
        if(x==3) {
            if((k[a[1][l]]+k[a[2][l]]+xx)%n==k[a[3][l]]) {
                xx=(k[a[1][l]]+k[a[2][l]]+xx)/n;
                if(dfs(l-1,1)) return 1;
                else {xx=pr; return 0;}
            }
            else return 0;
        }
        else {
            if(dfs(l,x+1)) return 1;
            return 0;
        }
    }
    else {
        if(x==3) {
            int tp=(k[a[1][l]]+k[a[2][l]]+xx)%n;
            if(ok[tp]&&ok[tp]!=a[l][3]) return 0;
            if(ok[tp]) {
                xx=(k[a[1][l]]+k[a[2][l]]+xx)/n;
                if(dfs(l-1,1)) return 1;
                else {xx=pr; return 0;}
            }
            else {
                k[a[x][l]]=tp; ok[tp]=a[x][l];
                xx=(k[a[1][l]]+k[a[2][l]]+xx)/n;
                if(dfs(l-1,1)) return 1;
                k[a[x][l]]=-1; ok[tp]=0; xx=pr;
                return 0;
            }
        }
        else {
            for(register int i=0;i<n;i++) if(!ok[yh[i]]){
                k[a[x][l]]=yh[i]; ok[yh[i]]=a[x][l];
                if(check(l)) {if(dfs(l,x+1)) return 1;}
                k[a[x][l]]=-1; ok[yh[i]]=0; xx=pr;
            }
        }
    }
    return 0;
}

void read() {
    scanf("%d",&n);
    char ch=getchar();
    for(int i=1;i<=3;i++) {
        int sz=-1;
        while(ch<'A'||ch>'Z') ch=getchar();
        for(;ch>='A'&&ch<='Z';ch=getchar()) a[i][++sz]=ch;
    }
}

int main()
{
    read();
    memset(k,-1,sizeof(k));
    for(register int i=0;i<n;i++) yh[i]=n-i-1;
    dfs(n-1,1);
    for(register int i=0;i<n;i++) {
         printf("%d ",k['A'+i]);
    }
    printf("\n");
    return 0;
}
View Code

 

31.斗地主/斗地主增强版

搜索+贪心神题。

不想说话。一个点一个点改。

再也不写这种神题了,再写剁手。

//Twenty
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
typedef long long LL;
using namespace std;
int T,n,a[16],tp,ans;
char s[5];

void work(int now) {
     int b[16],p[10];
     for(int i=1;i<=5;i++) p[i]=0;
     for(int i=1;i<=13;i++) {
         b[i]=a[i];
         p[a[i]]++;
     }
     if(a[14]&&a[15]) p[5]++;
     else if(a[14]||a[15]) p[1]++;
     while(p[4]) {
         if(p[5]&&(p[1]+p[2]<=p[3])) p[5]--;
         if(p[1]>=2) p[1]-=2;
         else if(p[2]>=2) p[2]-=2;
         else if(p[5]) p[5]--; 
         else if(p[2]&&p[3]&&(p[3]-1>=(p[1]+p[2]))) {p[3]--; p[1]++; p[2]--;}
         else if(p[4]>=2&&p[3]) p[3]--,p[4]--,p[2]++,p[1]++;
         else if(p[4]>=2&&p[1]) p[1]--,p[4]--,p[3]++;
         else if(p[3]&&p[1]) {p[3]--;p[1]--;p[2]++;}
         else if(p[2]) p[2]--;
         else if(p[4]>=2) p[4]--;
         p[4]--;
         now++;
     }
     while(p[3]) {
        if(p[1]) p[1]--;
        else if(p[2]) p[2]--;
        else if(p[5]) { p[5]--; p[1]++;}
        p[3]--;
        now++;
      }
      now+=(p[2]+p[1]+p[5]);
      ans=min(now,ans);
      return;
}

void dfs(int x,int now) {
    while(!a[x]&&x<=15) x++;
    if(x+1<=15) dfs(x+1,now); 
    if(x>=15) { work(now); return ;}
         
    int i;
    for(i=x;i<=12;i++) {
         if(!a[i]) break;
         a[i]--;
         if(i-x+1>=5) {
             dfs(x,now+1);     
         } 
    }
    for(int j=i-1;j>=x;j--) a[j]++;
    
    for(i=x;i<=12;i++) {
         if(a[i]<2) break;
         a[i]-=2;
         if(i-x+1>=3) {
             dfs(x,now+1);     
         } 
    }
    for(int j=i-1;j>=x;j--) a[j]+=2;
    
    for(i=x;i<=12;i++) {
         if(a[i]<3) break;
         a[i]-=3;
         if(i-x+1>=2) {
             dfs(x,now+1);     
         } 
    }
    for(int j=i-1;j>=x;j--) a[j]+=3;
}

int main()
{
    scanf("%d%d",&T,&n);
    while(T--) {
        ans=n;
        for(int i=1;i<=15;i++) a[i]=0;
        for(int i=1;i<=n;i++) {
            int x,y;
            scanf("%d%d",&x,&y);
            if(x>=3&&x<=13) a[x-2]++;
            else if(x==1) a[12]++;
            else if(x==2) a[13]++; 
            else if(y==1) a[14]++;
            else a[15]++;
        }
        dfs(1,0);
        printf("%d\n",ans);
    }
    return 0;
}
View Code

数据造福人类(洛谷数据,来自在下,ylg,llj,sxy)

1.in100 2
13 2
9 3
3 2
9 1
6 4
6 3
1 3
6 4
9 3
8 2
8 3
7 4
8 4
10 4
3 3
5 3
4 3
6 2
5 1
12 3
11 3
12 4
12 2
9 2
7 4
8 2
0 1
1 3
13 3
8 3
12 3
4 2
1 1
4 4
4 3
11 3
3 4
5 4
1 4
2 2
3 4
9 1
6 1
11 2
7 3
1 1
9 4
11 3
11 4
12 1
6 2
4 2
9 3
13 4
8 3
3 3
1 2
8 2
2 2
11 3
7 1
13 3
13 4
5 2
10 1
7 4
11 2
0 2
3 2
8 1
7 1
10 4
0 1
1 3
12 1
3 4
8 1
4 1
11 4
7 3
2 1
1 1
9 3
6 4
8 1
3 2
13 1
4 4
3 2
10 1
13 2
0 1
13 4
13 1
1 1
4 4
11 1
2 3
4 1
1 4
1 2
2 1
5 3
5 4
3 3
1 3
13 1
6 1
4 3
10 2
1 4
11 4
11 3
9 3
9 3
11 1
13 3
11 3
4 1
12 2
11 4
11 3
13 4
10 4
12 4
5 1
4 3
9 4
6 2
3 4
10 2
7 2
8 1
7 4
6 1
2 3
12 3
2 3
7 3
13 1
9 1
8 1
10 3
3 3
2 2
3 2
4 4
5 3
8 2
13 1
13 3
8 3
3 1
12 1
13 4
5 3
9 3
7 2
9 4
6 4
12 2
11 1
4 2
4 1
2 2
7 3
5 2
8 3
8 4
6 3
1 2
10 4
9 2
9 4
9 4
4 3
4 4
2 2
6 1
7 3
5 3
7 2
9 4
2 4
2 1
10 3
5 1
10 1
1 1
2 1
1 2
3 4
5 4
7 1
12 2
5 2
5 4
2 1
3 2
13 31.out2
2
1
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
1
2
2
2
2
1
2
2
2
2
2
2
2
2
1
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
1
2
2
2
2
1
2
2
2
2
2
2
2
2
2
2
2
2
26.in100 10

7 3
8 1
4 1
11 2
5 2
7 2
6 1
2 1
4 2
11 4

13 1
10 3
11 1
7 3
1 4
5 4
3 1
7 4
8 4
10 1
2 3
10 2
4 3
6 3
10 4
7 3
3 4
10 1
7 4
13 4
6 1
1 3
8 4
11 2
13 3
12 3
3 3
10 2
13 4
8 3
11 3
5 3
13 4
13 1
11 1
4 1
6 2
8 2
7 1
7 2
8 3
13 3
12 4
8 1
7 2
0 2
11 1
4 4
13 4
0 1
2 2
0 1
10 4
2 3
1 3
5 2
6 1
4 2
6 3
9 3
12 1
10 2
5 3
6 3
7 1
2 2
3 3
8 1
8 3
11 2
5 1
4 2
12 4
11 1
10 2
5 3
2 4
5 2
8 2
1 4
4 3
11 2
1 1
7 3
4 4
4 2
10 4
7 1
12 3
5 3
11 3
11 4
13 1
5 2
13 3
5 4
2 4
8 3
6 4
2 3
7 4
11 3
0 1
10 3
7 2
4 1
7 1
3 4
13 2
9 3
8 3
13 4
13 3
7 1
8 2
5 4
2 4
9 4
9 2
11 4
1 4
3 2
1 3
11 3
10 1
1 1
10 4
8 1
11 1
6 2
3 4
3 1
9 1
1 4
8 3
4 4
13 4
2 2
11 4
10 4
10 3
8 2
5 3
6 1
13 1
13 3
10 4
3 1
11 3
1 3
10 3
13 4
12 2
8 1
10 2
2 4
5 3
6 2
12 4
1 3
2 2
12 3
9 4
4 4
3 1
6 2
11 4
9 1
3 2
11 2
11 4
1 3
3 2
6 3
7 4
3 1
5 2
1 2
9 3
10 3
11 2
1 3
4 1
8 4
12 1
6 2
7 3
10 2
1 4
9 1
4 2
5 4
13 2
1 3
8 4
6 1
6 3
0 1
9 1
12 3
10 4
3 1
11 1
1 3
8 1
11 4
7 4
10 3
13 3
13 4
13 4
6 2
3 2
1 2
11 4
13 2
4 4
4 1
11 3
2 2
4 1
3 3
2 3
5 1
10 1
2 1
6 4
1 1
0 2
8 1
6 4
5 3
1 1
2 1
11 3
3 2
13 2
1 2
12 2
9 3
9 1
6 3
9 3
6 2
7 1
4 2
8 2
11 4
13 4
4 4
6 4
8 1
6 3
4 3
11 3
12 1
3 3
1 2
12 4
7 3
3 3
11 2
10 4
12 3
2 2
2 4
5 4
2 1
13 2
4 1
10 3
4 1
8 1
7 2
9 4
9 1
11 2
6 3
5 4
3 4
1 4
6 4
7 2
9 1
2 2
8 3
9 4
8 2
1 3
2 1
13 1
2 1
8 4
10 2
2 3
11 3
13 3
3 2
11 4
11 1
11 3
2 2
8 4
3 2
3 1
10 1
5 3
0 2
4 1
12 2
1 3
11 3
6 4
7 4
4 4
8 3
5 3
13 4
5 4
3 1
3 4
9 1
1 2
6 2
8 3
9 3
10 4
5 2
8 4
1 3
10 1
6 1
2 4
6 4
0 2
0 1
11 1
3 2
3 3
6 2
8 4
4 3
6 3
7 4
8 2
7 3
0 1
5 1
6 2
13 2
13 4
11 4
3 2
2 2
5 1
10 4
3 1
0 2
9 4
4 4
5 3
9 4
8 4
3 2
4 3
13 1
12 1
9 2
10 2
2 3
6 4
1 1
13 2
2 4
6 3
12 1
1 2
10 3
7 3
5 3
6 2
5 4
4 3
10 3
3 1
0 2
2 2
2 3
9 4
10 2
11 3
2 2
9 1
13 4
10 3
9 2
10 1
9 4
9 3
8 3
4 1
13 2
2 1
4 3
7 3
8 4
13 3
11 3
8 2
2 2
3 3
8 1
3 2
12 2
11 2
5 1
1 1
10 1
5 3
9 2
2 3
6 4
8 3
13 2
7 2
12 3
10 2
1 2
6 2
9 1
5 3
9 4
13 1
1 2
12 2
1 4
10 3
11 3
10 1
0 2
4 1
3 3
13 1
5 2
11 4
9 3
2 2
7 2
4 2
5 3
9 3
13 2
8 2
1 2
5 4
12 1
4 4
12 3
6 1
6 2
4 4
9 3
0 2
13 3
8 3
10 2
13 2
1 3
9 1
4 3
9 4
11 2
1 3
10 1
11 4
1 2
6 4
10 4
12 3
6 2
9 4
3 3
5 3
13 4
7 3
9 3
3 4
7 1
1 3
6 2
6 2
4 1
1 2
13 2
11 4
11 1
9 4
4 2
8 2
6 1
10 2
8 3
2 4
12 2
0 1
2 3
3 1
12 4
4 2
11 4
7 4
4 4
12 2
12 3
10 4
11 3
12 4
3 3
9 1
1 3
6 4
8 1
6 1
13 2
2 3
4 3
3 3
9 3
10 3
3 1
1 4
8 1
7 3
10 3
5 3
0 2
5 1
2 3
2 2
12 1
12 4
6 1
12 1
5 1
10 1
5 4
0 2
1 3
8 3
9 4
5 4
9 1
3 4
9 4
12 4
2 2
12 1
5 1
11 4
10 4
7 2
6 1
12 2
12 4
3 4
10 1
5 4
2 2
4 4
7 3
6 3
6 2
4 4
7 2
1 1
9 4
6 4
3 4
4 1
2 2
8 1
3 4
5 3
3 3
7 3
11 2
0 1
1 3
4 2
1 2
10 3
1 4
9 4
4 1
2 3
5 2
13 3
5 4
1 1
4 4
7 3
9 1
4 4
10 4
4 3
6 1
1 4
8 4
12 3
3 4
6 2
6 3
0 2
8 4
2 1
13 1
0 1
12 1
5 3
8 3
10 4
4 2
7 3
3 2
2 2
1 3
7 2
9 2
3 4
3 3
13 1
6 3
10 2
3 4
9 2
7 4
2 3
10 1
8 2
12 3
6 4
2 3
3 2
9 3
7 1
10 3
1 4
0 2
11 4
1 3
11 1
2 3
10 3
4 4
10 4
3 4
12 1
11 3
13 3
9 3
7 1
11 2
0 1
3 2
8 1
13 4
12 2
8 3
12 4
7 2
9 3
7 4
8 2
13 2
0 1
9 1
13 4
2 1
9 4
2 4
9 2
4 3
7 1
1 3
12 1
5 1
11 2
3 2
2 1
3 3
0 1
4 4
11 2
4 2
1 2
1 3
2 1
5 4
8 4
12 4
9 3
1 2
10 1
9 2
4 4
7 3
13 2
2 1
12 3
7 4
1 1
4 1
5 1
9 2
11 3
11 1
10 4
13 3
12 1
12 4
1 1
13 4
2 3
3 2
9 4
3 4
10 1
12 4
1 4
13 3
5 3
6 3
3 2
12 1
6 1
4 2
2 4
12 2
5 4
3 4
13 3
6 1
13 4
12 4
12 2
7 2
13 1
2 1
2 3
7 3
12 1
6 2
13 1
8 3
8 4
0 2
1 1
2 3
5 2
7 3
9 4
5 2
5 4
1 3
4 2
3 3
1 1
13 1
3 4
10 2
5 1
12 4
10 1
6 3
6 2
7 1
5 4
1 3
2 2
7 3
6 2
3 4
9 2
5 1
12 1
0 1
2 4
8 1
8 3
1 4
3 2
13 2
4 4
6 3
6 2
12 1
6 1
7 4
13 3
10 2
1 1
7 4
10 2
4 4
12 1
5 1
11 2
11 1
3 4
2 1
3 2
8 2
12 3
0 1
8 3
11 4
0 2
1 1
12 1
9 1
12 1
4 3
13 3
5 4
6 1
3 4
10 1
7 4
11 3
5 1
0 2
12 2
5 1
2 1
10 1
9 4
12 3
1 4
3 1
7 3
4 1
6 3
9 1
4 3
7 1
11 1
6 4
0 2
13 4
1 2
12 4
1 1
2 4
3 4
8 4
12 2
2 3
8 1
9 4
7 3
0 1
5 4
11 4
6 2
12 4
8 3
12 3
3 1
7 1
2 4
3 3
11 4
13 2
11 1
2 1
0 1
12 1
2 3
4 1
5 4
3 4
2 4
12 2
6 3
8 2
7 4
13 4
12 3
11 1
10 1
8 4
9 1
13 3
11 2
7 3
2 1
2 3
7 1
3 3
11 1
2 2
8 2
1 3
3 4
3 2
3 1
10 3
6 1
13 3
7 4
6 3
12 1
3 4
3 2
8 3
5 4
7 4
9 1
2 1
11 3
0 1
4 3
1 1
12 1
6 1
0 2
9 2
13 4
7 4
8 1
13 1
6 4
1 2
8 2
9 1
8 3
1 3
11 3
9 3
11 1
2 4
7 1
11 2
4 4
5 4
0 2
2 2
12 4
7 3
8 2
10 1
12 4
7 4
7 1
0 2
1 4
11 2
12 1
11 3
2 1
5 1
6 3
7 2
7 1
10 4
1 1
8 4
10 3
3 2
13 3
13 4
6 2
7 4
1 1
5 1
9 4
7 1
2 1
6 3
7 2
12 3
3 1
13 3
12 1
6 1
13 4
3 3
6 2
0 1
10 36.out5
8
6
5
4
7
8
9
7
6
6
7
7
5
9
8
8
7
8
3
9
7
7
9
9
7
8
7
2
6
5
9
5
7
5
5
9
9
8
8
4
6
4
6
5
8
8
7
6
7
7
8
7
8
8
8
7
5
6
8
7
5
7
6
6
9
6
7
5
9
8
8
5
7
6
4
9
7
5
9
6
9
7
6
9
8
7
9
8
9
7
7
5
9
6
8
7
8
6
611.in100 15
1 1
1 2
8 4
3 2
6 4
2 4
7 3
12 4
4 2
9 3
7 2
9 1
13 2
3 3
13 1
9 2
8 2
11 2
1 4
4 1
11 4
1 3
10 2
5 4
6 4
2 4
10 3
11 3
2 2
3 2
0 1
3 2
2 1
9 4
10 3
1 4
2 2
7 3
13 1
10 4
1 2
8 4
13 4
1 3
9 1
10 1
13 4
0 1
13 2
12 2
8 4
8 3
7 1
2 4
6 1
11 1
10 2
7 3
3 4
6 3
9 1
3 4
8 1
5 3
12 4
10 4
12 1
6 2
11 1
6 3
13 1
9 3
6 1
7 4
0 2
13 3
4 1
12 1
3 1
5 2
2 3
4 2
1 3
11 4
5 3
11 3
13 2
9 2
6 3
2 4
11 3
0 1
2 4
11 2
9 4
6 2
7 4
9 1
11 4
12 3
12 4
8 1
4 4
12 1
0 2
5 4
7 2
8 1
10 4
9 4
2 2
10 3
12 3
11 3
0 1
6 1
10 2
5 2
12 1
13 3
1 4
12 1
9 4
9 2
5 2
12 3
10 3
13 2
2 1
10 2
3 3
1 2
8 1
6 2
3 2
10 3
5 2
8 3
2 2
6 4
5 4
7 1
9 4
9 2
11 4
8 2
3 4
1 4
10 1
3 3
8 4
5 2
4 2
5 4
9 3
13 2
5 3
11 1
10 1
4 1
3 1
8 3
10 3
9 2
9 1
3 3
7 3
1 4
8 4
8 2
5 1
1 1
7 1
3 2
12 1
11 4
12 3
8 3
5 4
8 1
7 2
1 2
2 1
8 1
7 4
12 3
11 4
7 3
5 3
6 3
9 2
4 4
11 1
2 2
9 3
3 3
10 1
6 1
10 3
7 3
12 4
13 1
9 4
7 4
1 3
11 1
7 1
8 1
11 2
8 3
13 4
1 1
4 3
8 3
12 4
4 1
10 3
7 3
4 2
9 3
11 4
7 1
10 4
0 2
1 3
8 2
4 3
4 1
5 2
7 2
1 2
9 1
12 4
1 1
3 4
13 2
8 1
0 2
2 3
7 3
4 2
13 1
1 1
0 2
12 4
9 4
7 4
5 1
8 3
4 1
9 2
6 4
6 3
9 3
10 3
12 2
12 4
7 1
11 4
10 1
2 4
5 4
3 3
13 4
6 2
11 1
1 1
10 2
8 1
11 3
5 4
8 4
10 4
1 1
5 3
8 3
9 3
6 4
7 4
7 2
10 1
6 2
6 3
11 2
13 2
6 4
7 3
13 3
4 4
13 1
6 2
13 4
2 1
3 3
9 3
6 3
11 1
11 2
0 1
4 3
4 4
13 3
7 1
9 3
13 1
8 4
3 4
7 3
2 4
13 4
3 2
12 1
10 4
5 2
8 1
4 1
13 3
12 1
8 4
3 1
4 3
10 4
1 3
0 2
10 2
13 4
12 3
2 3
5 3
8 1
3 3
6 2
13 2
8 2
4 1
5 2
1 1
9 2
2 4
1 3
10 3
12 3
13 4
7 2
10 4
9 3
13 4
0 1
12 1
2 4
7 1
4 2
11 2
2 3
6 1
9 1
7 3
8 3
7 4
13 3
2 2
3 1
11 3
8 1
12 1
5 2
9 4
10 3
10 4
13 3
12 2
3 4
11 4
4 1
1 1
8 2
1 2
2 1
9 3
4 2
13 2
6 4
1 1
7 1
4 1
12 2
0 1
12 3
0 2
7 2
9 4
10 2
9 3
2 4
7 2
5 2
11 2
6 3
1 1
13 3
4 1
8 2
8 1
3 4
1 3
9 4
12 2
10 4
12 4
1 2
1 1
2 4
7 1
7 2
9 3
3 4
4 3
7 4
11 2
1 3
1 1
13 1
0 1
12 4
5 3
2 3
7 4
13 3
11 3
4 1
3 3
10 4
6 1
5 1
4 2
10 3
9 2
11 2
1 2
6 3
8 2
13 3
9 1
13 2
2 1
0 1
3 1
1 4
9 3
13 4
10 4
12 3
6 4
11 3
8 3
12 2
5 4
0 2
8 4
1 3
2 2
3 1
13 1
4 2
3 3
11 1
13 1
10 3
7 1
1 2
7 4
2 2
3 3
13 3
5 2
9 1
11 4
7 2
11 2
6 2
6 4
3 3
7 2
12 2
10 2
4 2
9 4
0 1
2 4
9 3
13 3
3 4
2 2
5 4
0 2
6 1
9 4
10 3
5 1
6 3
11 3
13 1
12 4
7 4
11 1
8 1
7 3
2 1
10 2
1 3
13 3
6 3
9 1
12 3
1 1
1 3
4 2
8 2
7 1
9 2
8 4
5 1
12 4
7 2
2 4
13 4
8 1
2 3
4 1
6 2
3 2
11 4
6 3
1 1
5 2
11 2
1 2
4 2
12 4
11 3
12 2
13 4
10 2
10 1
4 4
9 2
8 3
10 4
4 3
2 1
7 4
3 1
6 3
5 1
8 2
7 3
11 2
9 4
10 4
6 4
13 4
11 3
7 1
10 1
1 2
8 2
5 3
7 4
2 2
12 4
10 4
11 3
7 4
12 2
12 4
8 2
4 3
12 1
1 4
2 3
4 4
7 2
10 2
4 2
10 1
13 1
3 2
9 2
4 4
10 3
2 3
6 3
11 4
4 3
5 1
13 3
2 4
12 1
12 2
0 2
0 2
11 3
7 1
12 1
2 3
5 1
9 1
7 3
10 1
4 2
8 3
6 1
10 4
4 3
11 2
0 2
2 4
10 1
4 4
8 1
4 2
4 3
7 1
11 4
11 2
6 3
11 3
8 4
12 3
9 2
3 3
12 1
0 1
1 2
4 4
4 1
0 2
6 3
3 2
4 3
10 1
13 4
9 2
1 4
9 4
11 4
12 1
3 4
5 3
12 3
6 1
8 3
13 4
10 3
5 4
3 2
4 1
8 2
10 2
4 3
2 2
5 3
8 4
10 2
8 1
9 2
0 2
5 1
2 3
10 4
8 2
2 1
7 2
13 4
9 1
12 4
12 2
6 1
11 2
4 2
10 3
3 2
4 4
1 2
2 2
7 3
12 3
6 3
2 4
13 2
5 1
9 4
11 1
12 4
13 3
1 4
10 4
10 3
7 4
11 2
8 4
11 4
11 3
12 3
12 2
13 3
13 4
7 1
12 2
2 1
2 4
10 3
11 4
6 3
4 3
11 1
13 1
5 1
5 3
9 2
5 2
0 2
2 4
6 1
1 2
3 2
9 1
2 1
12 4
5 3
9 3
8 3
7 2
8 1
3 1
5 1
4 1
6 1
13 4
10 1
6 4
4 3
5 4
1 2
13 1
9 4
3 4
1 3
12 1
9 3
7 3
13 4
5 2
9 2
12 1
6 4
3 3
8 2
13 2
1 2
4 3
0 1
5 3
9 1
6 2
9 4
13 4
8 4
0 2
5 3
5 2
11 2
4 2
13 2
9 1
3 2
12 2
4 1
0 1
9 3
10 2
0 2
2 2
11 4
13 1
13 3
12 1
11 2
0 1
7 2
2 3
7 4
6 4
4 2
11 3
0 1
8 4
1 2
4 1
13 2
6 2
10 3
5 3
2 4
1 4
7 1
8 3
4 3
4 4
11 4
9 2
11 1
9 3
12 1
7 3
10 2
3 1
2 1
13 2
12 2
4 3
0 1
3 4
5 3
4 2
11 1
8 3
6 4
9 4
5 2
4 2
11 2
10 1
5 4
7 4
3 3
9 2
11 3
0 1
8 4
9 4
13 2
6 1
8 1
3 3
3 2
11 2
13 1
3 4
2 4
5 4
6 2
1 2
4 2
2 1
5 1
12 2
13 1
11 3
2 3
7 4
7 2
1 2
2 1
8 3
8 4
1 4
12 1
11 4
2 4
1 3
13 1
7 1
10 3
2 3
1 1
7 4
10 1
13 3
8 3
8 4
3 4
13 4
0 2
6 4
13 2
13 3
8 3
6 4
10 3
13 1
5 4
7 2
6 2
4 1
1 1
11 2
8 4
2 2
8 2
0 2
9 3
4 2
9 4
8 2
3 3
7 3
13 2
6 3
8 1
5 3
5 2
1 2
6 4
11 2
13 3
11 3
13 1
0 1
3 1
10 2
9 1
7 3
2 1
6 2
1 3
11 1
3 2
8 2
8 1
9 2
13 4
0 2
2 2
12 2
10 1
8 4
8 1
5 4
11 2
4 1
1 1
5 2
2 3
10 3
12 4
4 1
5 2
1 2
11 4
6 3
3 1
12 1
10 1
0 2
10 2
12 2
8 1
1 1
13 3
10 1
12 2
9 4
10 4
7 2
4 4
12 4
12 3
8 2
8 4
3 2
4 2
5 1
1 1
11 1
2 4
8 2
0 1
1 3
13 3
7 1
12 4
5 1
11 1
11 2
3 2
12 3
2 3
2 2
5 2
1 4
12 3
13 1
10 4
2 3
8 4
7 4
11 2
12 4
5 4
4 1
7 2
11 3
12 2
5 3
9 1
8 1
1 1
0 1
5 1
2 2
13 2
6 2
9 3
3 2
7 3
13 1
11 1
5 2
6 4
13 4
5 4
6 3
12 1
3 1
10 1
10 4
6 4
9 2
8 4
3 4
1 3
4 4
8 1
3 3
4 1
11 4
7 1
6 2
13 1
5 4
11 3
5 2
7 4
13 2
7 2
9 3
11 1
12 4
8 3
8 4
8 3
11 2
1 4
10 3
11 1
5 4
3 3
13 1
5 3
6 4
3 2
12 1
13 3
6 3
6 4
10 1
2 1
7 4
9 2
7 2
6 1
7 3
8 2
11 1
13 4
13 3
6 3
12 1
2 4
3 4
11 4
12 1
5 1
2 4
8 1
3 3
12 4
9 3
13 3
8 3
11 3
11 2
2 3
13 1
8 4
4 1
6 2
7 4
9 1
13 3
8 3
3 2
4 2
12 4
7 3
0 2
0 1
4 4
5 4
9 3
2 2
6 2
7 2
13 3
12 3
12 4
3 4
7 1
5 2
4 3
11 2
1 2
7 4
11 4
3 3
2 4
7 3
2 2
1 4
12 3
8 2
5 3
4 3
1 2
12 1
1 1
2 3
3 2
5 1
4 3
0 1
7 1
12 4
1 4
9 3
5 4
10 4
10 2
8 3
1 2
13 3
0 2
12 3
9 4
4 2
2 2
10 2
12 1
0 1
2 4
3 2
8 3
6 3
7 4
8 1
9 1
0 2
7 3
12 2
8 2
3 4
13 3
1 4
9 3
3 2
1 1
9 2
13 4
4 1
8 4
4 4
9 4
12 4
7 1
11 3
8 2
4 3
13 1
5 2
1 3
12 2
13 2
0 1
7 1
9 4
6 1
3 2
8 4
11 2
12 1
10 2
13 2
3 2
9 1
5 3
13 3
6 1
11 4
12 4
1 3
2 3
9 3
2 4
1 2
11 2
7 1
10 1
12 1
0 2
8 2
5 4
11 3
9 4
1 3
6 2
6 1
4 3
5 3
13 1
2 3
10 4
3 2
12 3
7 2
2 4
6 3
5 2
5 1
1 4
1 2
2 2
9 4
8 3
2 1
13 1
8 2
6 4
4 2
1 4
13 4
12 1
13 3
9 2
1 2
3 3
7 3
8 4
10 1
11 4
1 2
9 1
0 1
2 2
9 3
7 1
11 1
12 3
12 1
13 2
12 4
11 4
10 4
10 2
13 1
6 2
5 4
3 4
1 1
0 1
1 4
10 2
6 1
8 2
9 4
11 1
3 1
7 2
0 2
4 4
2 3
5 1
8 2
3 4
10 1
13 4
7 2
9 1
6 4
13 1
13 2
13 3
9 3
10 2
11 3
7 3
11 4
1 1
7 2
3 4
4 4
9 4
3 2
8 1
10 1
2 1
8 2
12 3
7 4
12 2
5 3
4 1
4 3
9 4
11 2
9 2
7 1
11 1
2 2
9 1
9 3
3 4
1 1
2 3
6 2
2 2
8 2
10 3
8 1
5 3
5 4
8 3
7 1
2 4
1 1
10 2
4 3
4 2
1 4
13 1
4 4
5 2
1 3
2 1
12 1
7 1
12 3
9 1
6 1
7 4
4 3
6 2
8 2
11 1
5 4
2 1
12 2
11 4
5 2
7 4
11 1
10 1
7 3
1 2
10 2
9 3
8 3
1 1
13 3
3 2
1 1
0 2
2 4
10 1
6 2
4 3
9 1
9 4
10 4
6 1
2 1
5 1
11 1
7 1
12 1
1 3
2 1
10 1
3 1
3 2
1 2
9 4
7 4
13 4
5 1
9 1
4 1
3 4
13 1
4 2
13 4
6 4
7 4
6 1
11 4
10 1
3 1
5 3
12 4
6 2
3 2
4 2
1 2
6 3
12 3
12 2
5 3
12 1
13 1
11 4
11 1
8 4
1 1
10 1
9 1
4 4
2 2
8 1
4 2
8 2
8 3
6 3
8 4
10 3
7 4
1 4
6 2
4 3
2 1
11 3
10 1
6 4
7 2
12 1
13 2
4 3
3 1
3 3
13 4
10 3
9 1
5 1
3 2
13 1
6 2
1 1
13 2
1 4
8 1
11 4
1 1
10 2
0 1
6 4
4 3
11 1
0 2
8 1
7 2
10 3
7 1
11 3
5 4
9 1
12 3
9 1
13 3
8 4
8 2
12 2
1 3
3 2
8 1
12 1
11 4
4 2
4 1
1 2
12 4
6 411.out10
9
8
8
6
10
7
6
10
8
6
5
7
5
5
11
8
10
7
7
9
10
6
9
6
10
6
7
7
8
9
8
8
5
8
9
6
4
5
9
7
5
8
7
6
7
4
8
9
7
8
8
8
9
9
5
9
7
8
7
9
8
7
10
7
9
8
10
9
5
7
3
7
7
8
6
10
8
7
7
8
5
4
5
6
5
4
7
4
7
7
7
11
8
4
6
6
8
6
7
普通
21.in1 17
7 3
4 2
5 2
10 1
10 3
3 3
13 4
4 4
7 2
0 2
4 1
13 3
7 4
4 3
10 4
5 4
0 121.out423.in1 8
1 1
1 2
1 3
1 4
2 1
2 2
2 3
2 423.out124.in1 22
9 1
6 1
12 1
12 4
3 3
6 3
12 2
7 3
3 4
7 4
13 3
12 3
7 1
3 2
10 2
13 4
11 4
10 3
6 2
6 4
4 3
13 224.out426.in1 19
5 4
11 1
0 1
3 3
6 2
6 1
5 3
5 1
6 4
8 1
12 1
5 2
0 2
8 3
13 4
13 3
13 1
8 4
12 226.out428.in1 22
1 2
12 4
7 3
0 1
8 3
4 4
2 3
0 2
6 4
8 4
6 1
10 2
7 4
1 3
2 2
1 4
6 2
4 2
8 2
4 3
12 2
2 128.out529.in1 20
7 1
5 3
11 3
10 1
12 4
2 1
5 2
8 1
9 2
2 2
8 2
4 3
7 3
10 2
5 4
9 3
6 1
2 4
2 3
13 429.out332.in1 22
3 1
3 2
3 3
3 4
5 1
5 2
5 3
5 4
7 1
7 2
7 3
7 4
9 1
9 2
9 3
9 4
11 1
11 2
11 3
13 1
13 2
2 132.out344.in1 11
9 1
6 1
6 2
8 1
9 2
8 2
1 1
6 3
8 3
9 3
9 444.out2
特殊

 -------------------------------------------------

更新一组数据 来自ykkkkkkk

【44.in】
1 11
9 1
6 1
6 2
8 1
9 2
8 2
1 1
6 3
8 3
9 3
9 4
【44.out】
2

  

 

32.潜伏者

粘个openjudge上的代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;
char a[110],b[110],c[110],d[110];
int main()
{
    int l1,l2,m=0;
    gets(a);
    gets(b);
    gets(c);
    l1=strlen(a);
    l2=strlen(c);
    for(int i=0;i<l1;i++)
    for(int j=0;j<l1;j++)
    if((a[i]==a[j]&&b[i]!=b[j])||(a[i]!=a[j]&&b[i]==b[j])){cout<<"Failed";return 0;}
    for(int i=0;i<l1;i++)
    d[a[i]]++;
    for(char i='A';i<='Z';i++)
    if(d[i]== 0){cout<<"Failed";return 0;}
    for(int i=0;i<l2;i++)
    for(int j=0;j<l1;j++) 
    if(c[i]==a[j]){c[i]=b[j];break;}
    puts(c);
    return 0;    
         
}
View Code

 

33.Hankson 的趣味题

水题。线筛预处理出质数,分解质因子,然后直接算答案。别忘了大于sqrt的质因子。

//Twenty
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
const int maxn=44725;
typedef long long LL;
using namespace std;
int T,p[maxn],bo[maxn],fl;

LL a0,a1,b0,b1,aa0[4650],aa1[4650],bb0[4650],bb1[4650],ans;

void get_prime() {
    for(int i=2;i<=44722;i++) {
	    if(!bo[i]) {p[++p[0]]=i;}
	    for(int j=1;j<=p[0]&&p[j]*i<=44722;j++) {
		    bo[i*p[j]]=1;
		    if(i%p[j]==0) break;
		}
	}
}

void work(LL x,LL y[]) {
    for(int i=1;i<=p[0]&&p[i]<=x&&x!=1;i++) if(x%p[i]==0){
        while(x%p[i]==0) {
		    y[i]++;
		    x/=p[i];
		}   
    }
    if(x!=1) y[4649]=x;
}

int main()
{
	get_prime();
	scanf("%d",&T);
	while(T--) {
		for(int i=0;i<4650;i++) aa0[i]=aa1[i]=bb0[i]=bb1[i]=0;
		ans=1LL; fl=0;
		scanf("%lld%lld%lld%lld",&a0,&a1,&b0,&b1);
		work(a0,aa0); work(b0,bb0);
		work(a1,aa1); work(b1,bb1);
		if(b1%a1!=0) fl=1;
		for(int i=1;i<=p[0];i++) {
		    if(aa1[i]>bb1[i]) {fl=1; break;}
		    LL up=bb1[i],dn=aa1[i];
		    if(aa0[i]>aa1[i]) up=min(up,aa1[i]);
			if(bb0[i]<bb1[i]) dn=max(dn,bb1[i]);
			if(up<dn) {fl=1; break;}
		    ans*=(up-dn+1);
		}
		if(aa1[4649]>bb1[4649]) fl=1;
		else if(bb1[4649]!=aa1[4649]) {
		    if(bb0[4649]==bb1[4649]) ans*=2;
		}
		if(fl) ans=0;
		printf("%d\n",ans);
	}
    return 0;
}

  

34.最优贸易

裸的spfa,难得的一A,这年的题好像比较水啊,至少前三道都挺水。

//Twenty
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
typedef long long LL;
using namespace std;
const int maxn=100005;
const int maxm=500005*2;
int ans,x,y,z,n,m,ecnt,a[maxn],dz[maxn],df[maxn];

void read(int &ret) {
    char ch=getchar(); ret=0;
    while(ch<'0'||ch>'9') ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0';
}

int fir[maxn],nxt[maxm],to[maxm],fif[maxn],nxf[maxm],tf[maxm];
void add(int u,int v) {
    nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
    nxf[ecnt]=fif[v]; fif[v]=ecnt; tf[ecnt]=u;
}

queue<int>que;
int vis[maxn];
void spfa(int fir[],int nxt[],int to[],int dis[],int s) {
     que.push(s);
     dis[s]=a[s];
     vis[s]=1;
     while(!que.empty()) {
	     int x=que.front();
	     que.pop(); vis[x]=0;
	     for(int i=fir[x];i;i=nxt[i]) {
		     int y=min(dis[x],a[to[i]]);
		     if(y<dis[to[i]]) {
			     dis[to[i]]=y;
			     if(!vis[to[i]]) {
				     vis[to[i]]=1;
				     que.push(to[i]); 
				 }
			 }
		 }
 	 }
}

int main()
{
    read(n); read(m);
    for(int i=1;i<=n;i++) read(a[i]);
    for(int i=1;i<=m;i++) {
	    read(x); read(y); read(z);
	    add(x,y); if(z==2) add(y,x);
	}
	memset(dz,127,sizeof(dz));
	memset(df,127,sizeof(df));
	spfa(fir,nxt,to,dz,1); 
	for(int i=1;i<=n;i++) a[i]=-a[i];
	spfa(fif,nxf,tf,df,n);
	for(int i=1;i<=n;i++) {
	    ans=max(ans,-df[i]-dz[i]);
	}
	printf("%d\n",ans);
    return 0;
}

  

35.靶形数独

这一年的Noip题是目前做过的最简单的。

搜索,模拟数独每次找可能填的数最少的格子填数。

貌似时限是2s但洛谷只给了1s,codevs上轻松地A了跑得还挺快,洛谷上卡卡常也可以过。

比较迷的是24行那句剪枝加上就会T第三个点,这究竟是为什么呀QAQ

//Twenty
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
typedef long long LL;
using namespace std;
int tp,x,a[10][10],okx[10][10],oky[10][10],okz[10][10],ans,fl;
int v[10][10]={0,0,0,0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,6,0,6,7,7,7,7,7,7,7,6,0,6,7,8,8,8,8,8,7,6,0,6,7,8,9,9,9,8,7,6,0,6,7,8,9,10,9,8,7,6,0,6,7,8,9,9,9,8,7,6,0,6,7,8,8,8,8,8,7,6,0,6,7,7,7,7,7,7,7,6,0,6,6,6,6,6,6,6,6,6};

int get(int x,int y) {
    if(x%3) x=x/3+1; else x=x/3;
    if(y%3) y=y/3+1; else y=y/3;
    return (x-1)*3+y;
}

void dfs(int rem,int now) {
    if(rem==0) {fl=1; ans=max(ans,now); return;}
    //if(now+rem*90<ans) return ;
    int tx=0,ty=0,mi=10;
    
    for(register int i=1;i<=9;i++) 
	    for(register int j=1;j<=9;j++) if(!a[i][j]) {
		    int tpp=9,zz=get(i,j);
		    for(register int k=1;k<=9;k++) {
			    if(okx[i][k]||oky[j][k]||okz[zz][k]) tpp--;
			}
			if(tpp<mi||tpp==mi) mi=tpp,tx=i,ty=j;
		}
    int tz=get(tx,ty);
    for(register int i=1;i<=9;i++) if(!okx[tx][i]&&!oky[ty][i]&&!okz[tz][i]) {
   	    a[tx][ty]=i;
   	    okx[tx][i]=1; oky[ty][i]=1; okz[tz][i]=1;
        dfs(rem-1,now+a[tx][ty]*v[tx][ty]);
        okx[tx][i]=0; oky[ty][i]=0; okz[tz][i]=0;
        a[tx][ty]=0;
    }
}

int main()
{
	tp=9*9;
	for(register int i=1;i<=9;i++) 
	    for(register int j=1;j<=9;j++) {
	        scanf("%d",&x);
	        if(x) {
	        tp--;
	        ans+=x*v[i][j];
	        a[i][j]=x;
	        okx[i][x]=1; 
			oky[j][x]=1;
			okz[get(i,j)][x]=1;
		    }
		}
	dfs(tp,ans);
	if(fl) {
		printf("%d\n",ans);
	}
	else printf("-1\n");
    return 0;
}

  

 

posted @ 2017-10-03 21:54  啊宸  阅读(1899)  评论(0编辑  收藏  举报