總結——關於2017 10 8測試的分析總結

来源:互联网 发布:淘宝没有添加销售属性 编辑:程序博客网 时间:2024/05/29 17:33

NOIP 2017 模拟



2017 10 8






T1 :


题目:





——正解思路:

将乘法问题转化为log相加问题,比较大小即可。

——我的乱搞:

变成除法问题,并剪枝,最后竟然Ac了。。。。



tips:

生命不息,数学不止。。。。



#include<cstdio>int n,m,t,fa,fb,mini;bool az,bz,fan;float zj,a[100001],b[100001];inline int read(){int i=0;float f=1.0;char c=getchar();while((c<'0'||c>'9')&&c!='-') c=getchar();if(c=='-') f=-1.0,c=getchar();while(c>='0'&&c<='9') i=(i<<3)+(i<<1)+c-48,c=getchar();return i*f;}int main(){t=read();while(t--){n=read();fa=0,fb=0;az=false,bz=false,fan=false;for(int i=1;i<=n;++i){a[i]=read();if(a[i]==0) az=true;if(a[i]<0) ++fa,a[i]=-a[i];}m=read();for(int i=1;i<=m;++i){b[i]=read();if(b[i]==0) bz=true;if(b[i]<0) ++fb,b[i]=-b[i];}if((fa-fb)&1){puts(fa&1 ? "Alice" : "Bob");continue;}else if((fa&1)&&(fb&1)) fan=true;if(az){puts(!fan ? "Alice" : "Bob");continue;}if(bz){puts(!fan ? "Bob" : "Alice");continue;}mini=n < m ? n : m;zj=1.0;for(int i=1;i<=mini;++i) zj*=a[i]/b[i];if(mini==n)for(int i=mini+1;i<=m;++i){zj/=b[i];if(zj<1) break;}elsefor(int i=mini+1;i<=n;++i){zj*=a[i];if(zj>1) break;}puts( !fan ? zj<1 ? "Alice" : "Bob" : zj>1 ? "Alice" : "Bob");}return 0;}





T2 :



题目 :





——正解思路:


dp , 转移方程为 f [ i ][ j ] = min ( f [ i + 1 ][ j + 1 ] ,  f [ i + 1 ][ j ] ,  f [ i ][ j + 1 ] ) + a1 [ i + 1 ] * b2 [ j + 1 ];


——我的乱搞:

我选择狗带。。。



正解:

varn, m, i, j : longint;a, b : array [0..2002] of longint;f : array [0..2002, 0..2002] of longint;function min (a, b, c : longint) : longint;begin        if a < b then                if a < c then exit (a)                else if c < b then exit (c)                else exit (b)        else                if b < c then exit (b)                else if c < a then exit (c)                else exit (a);end;begin        read (n, m);        for i := 1 to n do read (a[i]);        for i := 1 to m do read (b[i]);        fillchar (f, sizeof (f), 63);        f[n + 1][m + 1] := 0;        for i := n downto 1 do                for j := m downto 1 do                        f[i][j] := min (f[i + 1][j], f[i][j + 1], f[i + 1][j + 1]) + (a[i] - 1) * (b[j] - 1);        write (f[1][1]);end.




T3 : 


题目:




——正解思路:

用tarjan求双连通分量,然后答案减去每个双连通分量所可以产生的点的大小 C_size[ i ] ^ 2即可。

——我的乱搞:

双连通分量是什么鬼。。。。。惊恐



正解:

#include<stdio.h>#include<time.h>#include<algorithm>using namespace std;long long v[10001],ans;int n,cnt;inline long long read(){    long long i=0;    char ch;    for(ch=getchar();ch<'0'||ch>'9';ch=getchar());    for(;ch>='0' && ch<='9';ch=getchar())        i=(i<<3)+(i<<1)+ch-'0';    return i;}inline long long gcd(long long a,long long b){return !b?a:gcd(b,a%b);}inline int find(int n,long long aim){if(v[n]==aim) return n;int l=0,r=n,mid=(l+r)>>1;for(;l+1<r;mid=(l+r)>>1)v[mid]<aim?l=mid:r=mid;return r;}int main(){n=read();long long *a=new long long[n+1];long long *f=new long long[n+1];for(int i=1;i<=n;++i) a[i]=read();srand(time(0));random_shuffle(a+1,a+1+n);for(int i=1,p=min(n,4);i<=p;++i){register int num=0;for(long long j=1;j*j<=a[i];++j)if(a[i]%j==0){v[++num]=j;f[num]=0;if(j*j!=a[i]){v[++num]=a[i]/j;f[num]=0;}}sort(v+1,v+1+num);for(int j=1;j<=n;++j) ++f[find(num,gcd(a[i],a[j]))];for(int j=1;j<=num;++j){register long long total=0;if(v[j]<=ans) continue;for(int k=j;k<=num;++k)if(v[k]%v[j]==0) total+=f[k];if(total*2>=n) ans=max(ans,v[j]);}}int num=0;char c[13];    while(ans) c[++num]=(ans%10)+48,ans/=10;    while(num) putchar(c[num--]);    delete [] a;    delete [] f;    return 0;}


阅读全文
0 0