SDOI-07-DAY1

SDOI-07-DAY1

做了SDOI第一轮的一试题,差点被完虐。。。
内存限制竟然全部是2MB!!而且linux下arbiter,2MB竟然无法检测,全部判定为Wrong Answers!!
浪费了我好多时间。
第一题,递推+高精度,类似于AHOI2010的送分题。
我自以为聪明,用了和递推一样复杂度的模拟,结果90分。
原来,我那种算法对于n==1是不成立。。。。
(前几名中好像只有一个人AC了,其他和我一样90)
第二题,真的是模拟了,但需要一定的技巧,果断AC。
然后发现这个题我虐爆全场了,可能是因为我用cpp的原因。
第三题,最小路径覆盖。没有思路,本想写搜索,显然没有时间。
于是想贪心,考虑到答案可能会根据数据规模呈对数级增长,于是直接输出
2*int(log(n+m)/log(3.141592653*2))
【常数全是瞎编的,唯一的确定的是那个n+m,技巧就是随便弄几个小数据,都满足即可】
结果过了2个点。
后来看了题解,是转化成二分图做,正在研究中。
最后90+100+20=210,SD第4,考虑到最后一题爆0的概率,SD第5还有的
(NO3,4,5都是最后一题偏分的。。。最强的骗了30分)
(NO1,2 AC了最后一题,结果第二题。。。。)
第一题AC代码(M=1时输出2^D)
#include<cstdio>
#include
<cstring>
#include
<iostream>
#include
<fstream>
#include
<algorithm>
    
using namespace std;
#define MM(a,i) memset(a,i,sizeof(a))
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define NFOR(i,a,b) for(i=a;i<=b;i++)
#define DFOR(i,b,a) for(int i=b;i>=a;i--)
#define NDFOR(i,b,a) for(i=b;i>=a;i--)
#define PFOR(p,head,next) for(int p=head;p;p=next[p])
#define NPFOR(p,head,next) for(p=head;p;p=next[p])
    
const int INF=~0U>>2;
    
const int maxn=105;
    typedef 
long long int64;
//
    ifstream fin("rabbit.in");
    ofstream fout(
"rabbit.out");
    
int A[maxn][maxn];
    
int ans[maxn];
    
int main(){
        
int M,D;
        MM(A,
0),MM(ans,0);
        fin
>>M>>D;
        
if(M==1){
            ans[
0]=1,ans[1]=1;
            FOR(i,
1,D){
                FOR(k,
1,ans[0])ans[k]*=2;
                FOR(k,
1,ans[0])ans[k+1]+=ans[k]/10,ans[k]%=10;
                
if(ans[ans[0]+1])ans[0]++
                }

            DFOR(i,ans[
0],1)fout<<ans[i];
            fin.close();
            fout.close();
            
return 0;
            }

        A[M][
0]=1,A[M][1]=1;
        FOR(i,
1,D){
                FOR(k,
0,A[M][0])
                        A[M
+1][k]=A[M][k];
                FOR(k,
1,A[M-1][0]){
                        A[M][k]
+=A[M-1][k];
                        A[M][k
+1]+=A[M][k]/10;
                        A[M][k]
%=10;
                        A[M
-1][k]=0;
                        }

                
if(A[M][A[M][0]+1]>0)A[M][0]++;
                DFOR(j,M
-2,1)
                        FOR(k,
0,A[j][0])
                                A[j
+1][k]=A[j][k];
                FOR(k,
0,A[M+1][0])
                        A[
1][k]=A[M+1][k];
                
//FOR(j,1,M)printf("%d ",A[j][1]);printf("\n");
                }

        FOR(k,
0,A[M][0])
                ans[k]
=A[M][k];
        FOR(j,
1,M-1){
                FOR(k,
1,A[j][0]){
                        ans[k]
+=A[j][k];
                        ans[k
+1]+=ans[k]/10;
                        ans[k]
%=10;
                        }

                
if(ans[ans[0]+1]>0)ans[0]++;
                }

        DFOR(i,ans[
0],1)
                fout
<<ans[i];
        fin.close();
        fout.close();
        
return 0;
        }


第二题模拟链表水掉(手写的万能线性表传说)
#include<cstdio>
#include
<cstring>
#include
<iostream>
#include
<fstream>
#include
<algorithm>
using namespace std;
#define MM(a,i) memset(a,i,sizeof(a))
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define NFOR(i,a,b) for(i=a;i<=b;i++)
#define DFOR(i,b,a) for(int i=b;i>=a;i--)
#define NDFOR(i,b,a) for(i=b;i>=a;i--)
#define PFOR(p,head,next) for(int p=head;p;p=next[p])
#define NPFOR(p,head,next) for(p=head;p;p=next[p])
const int INF=~0U>>2;
const int maxn=100001;
typedef
long long int64;
//
ifstream fin("team.in");
ofstream fout(
"team.out");
short int team[maxn];
int last[301];
int next[maxn];
int head=-1,tail=-1;
string s,aa="ENQUEUE",bb="DEQUEUE",cc="STOP";
int main(){
int m,k,t;
MM(last,
0xff),MM(next,0xff),MM(team,0);
fin
>>m;
FOR(i,
1,m){
fin
>>k;
FOR(j,
1,k)
fin
>>t,team[t]=i;
}

s.clear();
for(;;){
fin
>>s;
if(s==cc)break;
else if(s==aa){
fin
>>t;
if(tail==-1){
head
=tail=t;
last[team[t]]
=t;
next[t]
=-1;
}

else if(last[team[t]]!=-1){
if(next[last[team[t]]]!=-1)
next[t]
=next[last[team[t]]];
else
tail
=t,next[t]=-1;
next[last[team[t]]]
=t;
last[team[t]]
=t;
}

else {
last[team[t]]
=t;
next[tail]
=t;
tail
=t;
next[t]
=-1;
}

}

else {
fout
<<head<<"\n";
if(last[team[head]]==head)last[team[head]]=-1;
if(head==tail)head=tail=-1;
else head=next[head];
}

s.clear();
}

fin.close();
fout.close();
return 0;
}


第三题是这样构图的:原边数n,构建一个X,Y集合各有n个节点的二分图,X表示发出,Y表示接受,
原图中a->b的有向边转化成二分图中x[a]与y[b]之间的无向边(目前见过的二分图都是无向的)
然后求出最大匹配数M 。 最终结果为n-M。我只有记结论的水平,证明略。
第三题AC代码(DINIC求最大匹配)
#include<cmath>
#include
<cstdio>
#include
<cstring>
#include
<iostream>
#include
<fstream>
#include
<algorithm>
    
using namespace std;
#define MM(a,i) memset(a,i,sizeof(a))
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define NFOR(i,a,b) for(i=a;i<=b;i++)
#define DFOR(i,b,a) for(int i=b;i>=a;i--)
#define NDFOR(i,b,a) for(i=b;i>=a;i--)
#define PFOR(p,head,next) for(int p=head;p;p=next[p])
#define NPFOR(p,head,next) for(p=head;p;p=next[p])
    
const int INF=~0U>>2;
    
const int maxn=2001;
    
const int maxm=20001;
//
    ifstream fin("trip.in");
    ofstream fout(
"trip.out");
    
int Q[maxm],H,T;
//
    int to[maxm],next[maxm],sc[maxm],snum=0;
    
int level[maxn],head[maxn],out[maxn];
//
    void init(){snum=1;MM(head,0);}
    
void insert(int x,int y,int c);
    
int max_flow(int n,int s,int t);
//
    int main(){
        
int n,m,a,b;
        fin
>>n>>m;init(); 
        FOR(i,
1,m)fin>>a>>b,insert(a+1,b+1+n,1);
        FOR(i,
1,n)insert(n+n+1,i,1),insert(i+n,n+n+2,1);
        fout
<<n-max_flow(n+n+2,n+n+1,n+n+2);
        fin.close();
        fout.close();
        
return 0;
        }
 
    
    
void insert(int x,int y,int c){
        snum
++,to[snum]=y,sc[snum]=c,next[snum]=head[x],head[x]=snum;
        snum
++,to[snum]=x,sc[snum]=0,next[snum]=head[y],head[y]=snum;}

    
int max_flow(int n,int s,int t){
        
int flow=0,cur;
        
for(;;){MM(level,0);
            H
=T=1,level[s]=1,Q[H]=s;
            
for(;H<=T;H++){int &t=Q[H];
                PFOR(p,head[t],next)
                    
if(sc[p]&&!level[to[p]])
                        T
++,level[to[p]]=level[t]+1,Q[T]=to[p];}

            
if(!level[t])break;
            FOR(i,
1,n)out[i]=head[i];
            
for(int q=0;;){
                
if(!q){
                    NPFOR(cur,
out[s],next)
                        
if(sc[cur]&&out[to[cur]]&&level[to[cur]]==2)
                            
break;
                    
if(cur)q++,Q[q]=cur,out[s]=next[cur];
                    
else break;
                    }

                
int u=to[Q[q]];
                
if(u==t){int dd=INF,ddl=0;
                    FOR(i,
1,q)if(sc[Q[i]]<dd)dd=sc[Q[i]],ddl=i;
                    flow
+=dd;
                    FOR(i,
1,q)sc[Q[i]]-=dd,sc[Q[i]^1]+=dd;
                    FOR(i,
1,q)if(!sc[Q[i]]){q=ddl-1;break;}
                    }

                
else {
                    NPFOR(cur,
out[u],next)
                        
if(sc[cur]&&out[to[cur]]&&level[u]+1==level[to[cur]])break;
                    
if(cur)q++,Q[q]=cur,out[u]=next[cur];
                    
else out[u]=0,q--;
                    }

                }
   
            }

        
return flow;
        }



你可能感兴趣的:(SDOI-07-DAY1)