雅礼中学考试第一场 20180105

先把题目和题解贴上去。

T1就不多说明了,没什么意思,以为很难,拿到题目的时候慌了一会,

思考了一会后,发现就是贪心。

代码如下,一次AC

 1 #include<cstring>
 2 #include<cmath>
 3 #include<cstdio>
 4 #include<iostream>
 5 #include<algorithm>
 6 
 7 using namespace std;
 8 inline int read()
 9 {
10     int x=0,f=1;char ch=getchar();
11     while(ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
12     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
13     return x*f;
14 }
15 
16 
17 int n;
18 char ch[100007];
19 int a[100007];
20 
21 bool check()
22 {
23     for (int i=1;i<=n/2;i++)
24         if (a[i]!=a[n-i+1]) return false;
25     return true;
26 }
27 bool jt()
28 {
29     int x=a[1],y=a[2];
30     for (int i=3;i<=n;i++)
31     {
32         if (i%2==1)
33         {
34             if (x!=a[i]) return false;
35         }
36         else 
37         {
38             if (y!=a[i]) return false;
39         }
40     }
41     return true;
42 }
43 bool yy()
44 {
45     for (int i=2;i<=n;i++)
46         if (a[i]!=a[i-1]) return false;
47     return true;
48 }
49 bool zj()
50 {
51     for (int i=2;i<=n/2;i++)
52     {
53         if (a[i]!=a[i-1]||a[n-i+2]!=a[n-i+1]) return false;
54     }
55     return true;
56 }
57 int main()
58 {
59     freopen("string.in","r",stdin);
60     freopen("string.out","w",stdout);
61 
62     int T=read();
63     while(T--)
64     {
65         n=read();
66         scanf("%s",ch+1);
67         for (int i=1;i<=n;i++)
68             a[i]=ch[i]-'0';
69         if (!check()) printf("1
");
70         else
71         {
72             if (jt()||yy()||zj()) printf("-1
");
73             else printf("2
");
74         }
75     }
76 }
View Code

T2

涨了知识吧,发现以前最最小割是真的不理解,通过这道题目有了更深的理解。

割了表示需要这里的花费。

所以S表示负的源点,T表示正的原点,割去与S相连的边就需要负的代价

T表示改点选了正点,这么选的代价就是h中的意义

然后发现答案一定未w的倍数,所以开始可以用系数来解决这道题目,

网络流不能流负边,那么就假设都取了负数,然后割了正的话讲边权改为两倍即可。

  1 #include<cmath>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstdio>
  5 #include<cstring>
  6 #include<queue>
  7 
  8 #define N 507
  9 #define M 20007
 10 #define inf 1000000007
 11 #define ll long long
 12 using namespace std;
 13 inline int read()
 14 {
 15     int x=0,f=1;char ch=getchar();
 16     while(ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
 17     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
 18     return x*f;
 19 }
 20 
 21 int n,w,p,q,S,T;
 22 int cnt,cur[N],hed[N],rea[M],val[M],nxt[M];
 23 int dis[N],u[N];
 24 ll ans;
 25 
 26 void add(int u,int v,int z)
 27 {
 28     nxt[++cnt]=hed[u];
 29     hed[u]=cnt;
 30     rea[cnt]=v;
 31     val[cnt]=z;
 32 }
 33 bool bfs()
 34 {
 35     memset(dis,-1,sizeof(dis));
 36     dis[S]=0;queue<int>q;q.push(S);
 37     while(!q.empty())
 38     {
 39         int u=q.front();q.pop();
 40         for (int i=hed[u];i!=-1;i=nxt[i])
 41         {
 42             //cout<<"i="<<i<<endl;
 43             int v=rea[i],fee=val[i];
 44             if (dis[v]!=-1||!fee)continue;
 45             dis[v]=dis[u]+1;
 46             if (v==T) return 1;
 47             q.push(v);
 48         }
 49     }
 50     return 0;
 51 }
 52 ll dfs(int u,int MX)
 53 {
 54     if (!MX||u==T) return MX;
 55     ll res=0;
 56     for (int i=cur[u];i!=-1;i=nxt[i])
 57     {
 58     //    if (i!=0) cout<<"i="<<i<<endl;
 59         int v=rea[i],fee=val[i];
 60     //    cout<<v<<" "<<fee<<endl;
 61         if (dis[v]!=dis[u]+1)continue;
 62         int x=dfs(v,min(MX,fee));
 63         val[i]-=x,val[i^1]+=x;
 64         cur[u]=i;
 65         if (x)
 66         {
 67             MX-=x,res+=x;
 68             if (!MX)break;
 69         }
 70     }
 71     if (!res)dis[u]=-1;
 72     return res;
 73 }
 74 void dinic()
 75 {
 76     while(bfs())
 77     {
 78     //    cout<<1<<endl;
 79         for (int i=S;i<=T;i++)cur[i]=hed[i];
 80         /*for (int i=1;i<=cnt;i++)cout<<nxt[i]<<" ";
 81         cout<<endl;*/
 82         ans+=dfs(S,inf);
 83     //    cout<<2<<endl;
 84     }
 85 }
 86 int main()
 87 {
 88     int Cas=read();
 89     while(Cas--)
 90     {
 91         cnt=1,memset(hed,-1,sizeof(hed));
 92         n=read(),w=read(),p=read(),q=read(),S=0,T=n+1;
 93         for (int i=1;i<=n;i++)u[i]=1;
 94         for (int i=1;i<=p;i++)
 95         {
 96             int x=read(),y=read(),z=read(),a=read(),b=read(),c=read(),d=read(),e=read(),f=read();
 97             add(x,y,2*a),add(y,x,0);
 98             add(y,x,2*a),add(x,y,0);
 99             add(y,z,2*b),add(z,y,0);
100             add(z,y,2*b),add(y,z,0);
101             add(z,x,2*c),add(x,z,0);
102             add(x,z,2*c),add(z,x,0);
103             u[x]+=d-f;
104             u[y]+=e-d;
105             u[z]+=f-e;
106         }
107         for (int i=1;i<=q;i++)
108         {
109             int x=read(),y=read(),z=read();
110             if (z==1)
111             {
112                 add(x,y,inf),add(y,x,0);
113                 add(y,x,inf),add(x,y,0);
114             }
115             else if (z==2)
116             {
117                 add(x,T,inf),add(T,x,0);
118                 add(S,y,inf),add(y,S,0);
119             }
120             else add(x,y,inf),add(y,x,0);
121         }
122         for (int i=1;i<=n;i++)
123         {
124             ans-=abs(u[i]);
125             if (u[i]>0) add(i,T,2*u[i]),add(T,i,2*u[i]);
126             else add(S,i,-2*u[i]),add(i,S,0);
127         }
128         dinic();
129         printf("%lld
",(ll)ans*w);
130         ans=0;
131     }
132 }
View Code

T3

题解解释的很清楚了。

发现一定是小的会赢,不管怎么,大的赢至少有奇数,偶数,不可能稳赢。

 1 #include<cstring>
 2 #include<cmath>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cstdio>
 6 
 7 #define ll long long
 8 #define mod 1000000007
 9 using namespace std;
10 inline int read()
11 {
12     int x=0;char ch=getchar();
13     while(ch<'0'||ch>'9'){ch=getchar();}
14     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
15     return x;
16 }
17 
18 int n,a,b;
19 ll ans[4],num[4];
20 bool flag;
21 
22 inline ll ksm(ll a,int b)
23 {
24     ll ans=1;
25     while(b)
26     {
27         if (b&1)(ans*=a)%=mod;
28         (a*=a)%=mod;
29         b>>=1;
30     }
31     return ans;
32 }
33 int main()
34 {
35     n=read(),a=read(),b=read();
36     if (a>b) swap(a,b),flag=1;
37     for (int i=1;i<=n;i++)
38     {
39         int x=read()%(a+b);
40         num[(x>=a)+(x>=b)+(x>=b&&x>=2*a)]++;
41     }
42     ans[0]=((ll)(ksm(2,num[1])-1)*ksm(2,num[2]+num[3]))%mod;//(2)存在就a必胜
43     (ans[0]+=(ll)(ksm(2,num[3])-num[3]-1+mod)*ksm(2,num[2]))%=mod;//存在两个xi>=2*a,a必胜,取了一次后就是(2),a必胜。
44     (ans[0]+=(ll)num[3]*(num[2]?ksm(2,num[2]-1):0))%=mod;//2a<=xi一个,并且奇数个(3)a,必胜。
45     ans[2]=((num[2]?ksm(2,num[2]-1):0)+(ll)num[3]*(num[2]?ksm(2,num[2]-1):1))%mod;
46     ans[3]=(num[2]?ksm(2,num[2]-1):1);
47     for (int i=0;i<4;i++)
48         ans[i]=(ll)ans[i]*ksm(2,num[0])%mod;//最后乘上num[0]表示随便取。
49     if (flag) swap(ans[0],ans[1]);
50     for (int i=0;i<3;i++)printf("%lld ",ans[i]);printf("%lld
",ans[3]);
51 }
View Code
原文地址:https://www.cnblogs.com/fengzhiyuan/p/8257879.html