2018.5.16 测试记

2018.5.17我兴高采烈地来到了机房,本来以为昨天他们已经考完试了,我就不用考了,结果,是我多虑了。mxl老师让我自己做做,然后给我测一下。

然后,我拿到了题目,哦哟,居然!....不会。好吧,我已经习以为常了。

看到第一题,解方程哦,好简单啊,可我就是不会呢。真的是,一点思路都没有。

 预计:0分   实际:0分

题解:用高斯消元求一下系数矩阵的逆矩阵,对于每次询问直接将其乘上逆矩阵即可

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn=110;
 7 const int maxm=1010;
 8 int n,m;
 9 double A[maxn][maxn+maxm];
10 double x[maxn];
11 inline double pr(double x) {
12     if(fabs(x)<1e-9)  return 0.000;
13     return x;
14 }
15 int main() {
16     freopen("equation.in","r",stdin);
17     freopen("equation.out","w",stdout);
18     scanf("%d%d",&n,&m);
19     for(int i=1; i<=n; i++)
20         for(int j=1; j<=n; j++)
21             scanf("%lf",A[i]+j);
22     for(int j=n+1; j<=n+m; j++)
23         for(int i=1; i<=n; i++)
24             scanf("%lf",A[i]+j);
25     for(int i=1; i<n; i++) {
26         int r=i;
27         for(int j=i+1; j<=n; j++)
28             if(fabs(A[r][i])<fabs(A[j][i]))  r=j;
29         for(int j=i; j<=n+m; j++)  swap(A[i][j],A[r][j]);
30         for(int j=i+1; j<=n; j++) {
31             if(A[j][i]==0)  continue;
32             for(int k=i+1; k<=n+m; k++)  A[j][k]-=A[i][k]/A[i][i]*A[j][i];
33             A[j][i]=0;
34         }
35     }
36     for(int i=1; i<=m; i++) {
37         x[n]=A[n][n+i]/A[n][n];
38         for(int j=n-1; j>0; j--) {
39             x[j]=A[j][n+i];
40             for(int k=j+1; k<=n; k++)  x[j]-=A[j][k]*x[k];
41             x[j]/=A[j][j];
42         }
43         printf("%.9f",pr(x[1]));
44         for(int j=2; j<=n; j++)  printf(" %.9f",pr(x[j]));
45         puts("");
46     }
47     return 0;
48 }

第二题,嗯。一开始是想到了很多的,但是奈于无法实现啊。然后,就想,如果m值不可分,是个奇数,那肯定是失败的,就输出“no”。还有,如果这个数一直分,一直除以2,如果次数还不如n,那也不行啊。(这是极端思想了,因为就算你是奇数,还可能有另一个数给你一半,你又变成偶数了)。

预计:40? 实际:70!

题解:

设d=gcd(a1,a2,...,an)可以证明若m=2^k*d则问题有解,否则问题无解。
令a1=b1*d,a2=b2*d,...,an=bn*d,找出所有bi为奇数的i,两两配对进行逆操作,如此所有的bi将变为偶数,d的值将会倍增,直到等于m为止。
倍增的次数为O(logm),配对的时间复杂度为O(n),故总时间复杂度O(nlogm)。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[10005];
int main()
{
    freopen("divide.in","r",stdin);
    freopen("divide.out","w",stdout);
    int t;
    cin>>t;
    while(t--)
    {
        int n,m;
        cin>>n>>m;
        for(int i=1; i<=n; i++)
        {
            cin>>a[i];
        }
        if(m%2==1||(n>2&&m/2%2==1))
        {
            cout<<"no"<<"\n";
            continue;
        }
        cout<<"yes"<<"\n";
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}
#include <cstdio>
#include <cstring>
int n,m,a[100010];
int p,u[1000010],v[1000010];
int gcd(int a,int b) {
    return b?gcd(b,a%b):a;
}
int main() {
    int t;
    freopen("divide.in","r",stdin);
    freopen("divide.out","w",stdout);
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d",&n,&m);
        int d=0;
        for(int i=1; i<=n; i++) {
            scanf("%d",a+i);
            d=gcd(d,a[i]);
        }
        m/=d;
        for(int i=1; i<=n; i++)  a[i]/=d;
        if((m&(-m))!=m)  printf("no\n");
        else {
            puts("yes");
            p=0;
            for(int d=0; m>>d; d++) {
                int l=0;
                for(int i=1; i<=n; i++)
                    if((a[i]>>d)&1) {
                        if(!l)  l=i;
                        else {
                            if(a[l]<=a[i]) {
                                a[i]-=a[l], a[l]<<=1;
                                u[++p]=l, v[p]=i;
                            } else {
                                a[l]-=a[i], a[i]<<=1;
                                u[++p]=i, v[p]=l;
                            }
                            l=0;
                        }
                    }
            }
            /*printf("%d\n",p);
            for(int i=p;i>0;i--) printf("%d %d\n",u[i],v[i]);*/
        }
    }
    return 0;
}

不得不说,我们某位同学,随机数都得了70分,emmm。

第三题,嗯。。。很迷,我居然得了20分。

预计:0分        实际:20分!

题解:最大权闭合子图模型,使用最小割建图

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int maxn = 500 + 10;
 5 const int INF = 1<<29;
 6 int x[maxn],y[maxn],r[maxn],ss[maxn];
 7 int tr[maxn],g[maxn][maxn];
 8 int n;
 9 int tt;
10 inline int sqr( int x ) {
11     return x*x;
12 }
13 int q[maxn];
14 int dis[maxn];
15 bool BFS() {
16     for(int i=1; i<=tt; i++) dis[i] = INF;
17     dis[tt] = 0;
18     int l=0,r=1;
19     q[1] = tt;
20     int x;
21     while( l<r ) {
22         x = q[++l];
23         tr[x] = 1;
24         for(int i=1; i<=tt; i++) if( dis[i]==INF && g[i][x] )
25                 dis[ q[++r] = i ] = dis[x] +1;
26     }
27     return dis[1]!=INF;
28 }
29 int dfs( int x,int nowd ) {
30     if( x==tt ) return nowd;
31     int z,cur = 0;
32     for( int &i = tr[x]; i<=tt; i++ ) if( g[x][i] && dis[i]==dis[x]-1 ) {
33             z = dfs(i,min(g[x][i],nowd));
34             if(z) {
35                 g[x][i]-=z;
36                 g[i][x]+=z;
37                 cur+=z;
38                 nowd-=z;
39                 if(nowd==0) break;
40             }
41         }
42 
43     if(cur==0) dis[x] = INF;
44     return cur;
45 }
46 int main() {
47     freopen("wifi.in","r",stdin);
48     freopen("wifi.out","w",stdout);
49     int ans;
50     scanf("%d",&n);
51     tt = n+2;
52     for(int i=1; i<=tt; i++)
53         for(int j=1; j<=tt; j++) g[i][j] = 0;
54     for(int i=1; i<=n; i++)
55         scanf("%d%d%d%d",x+i,y+i,r+i,ss+i);
56     for(int i=1; i<=n; i++) if( ss[i]>=0 )
57             g[1][i+1] = ss[i];
58         else
59             g[i+1][tt] = -ss[i];
60     for(int i=1; i<=n; i++)
61         for(int j=1; j<=n; j++) if(i!=j && sqr(x[i]-x[j])+sqr(y[i]-y[j]) <= sqr(r[i]) )
62                 g[i+1][j+1] = INF;
63     ans = 0;
64     for(int i=1; i<=n; i++) if(ss[i]>0) ans+=ss[i];
65     while( BFS() ) ans-=dfs(1,INF);
66     printf("%d\n",ans);
67     return 0;
68 }

我们的cdx大佬说,这套题,第一道和第三道是省选以下难度,noip以上,第二题才是noip难度。emmmm。然后他觉得这套题很弱智,就只交了第二道题,还是第一,因为他A了。

而我们这种蒟蒻,哎。

一世安宁

猜你喜欢

转载自www.cnblogs.com/GTBA/p/9051942.html