zoukankan      html  css  js  c++  java
  • diverta 2019 Programming Contest 2

      A:签到。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,m;
    signed main()
    {
    	n=read(),m=read();
    	if (m==1) cout<<0;else cout<<n-m;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      B:若将所有差是(p,q)的点对连接起来,显然会得到若干条链,链的数量即为答案。于是只要统计每种差的出现次数即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 55
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    typedef pair<int,int> pii;
    int n,ans;
    struct data{int x,y;
    }a[N];
    map<pii,int> f;
    signed main()
    {
    	n=read();
    	for (int i=1;i<=n;i++) a[i].x=read(),a[i].y=read();
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=n;j++)
    		if (i!=j)
    		{
    			ans=max(ans,++f[make_pair(a[i].x-a[j].x,a[i].y-a[j].y)]);
    		}
    	cout<<n-ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      C:显然应该尽量加正数减负数。但同时容易发现至少有一个数要被减掉,至少有一个数要被加上,所以均为正数或均为负数时稍微修改一下。不妨设是排序后要将前p个数减掉,其他数加上。那么令a1依次减去ap+1~an-1,再令an依次减去a1~ap即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 100010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,a[N];
    signed main()
    {
    	n=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	sort(a+1,a+n+1);
    	int p=0;
    	for (int i=1;i<=n;i++) if (a[i]<0) p=i;
    	p=max(p,1);p=min(p,n-1);
    	//让前p个被减掉
    	int s=0;
    	for (int i=1;i<=p;i++)  s-=a[i];
    	for (int i=p+1;i<=n;i++) s+=a[i];
    	cout<<s<<endl;
    	for (int i=p+1;i<n;i++)
    	{
    		printf("%d %d
    ",a[p],a[i]);
    		a[p]-=a[i];
    	}
    	printf("%d %d
    ",a[n],a[p]);a[n]-=a[p];
    	for (int i=1;i<p;i++)
    	{
    		printf("%d %d
    ",a[n],a[i]);
    		a[n]-=a[i];
    	}
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      D:显然A到B和B到A的过程是独立的,分别最优化即可。显然就是做一个完全背包。需要注意的是第二次完全背包值域是5000*5000,且答案会爆int。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N (5010*5010)
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,a[2][3];
    ll f[N];
    ll solve(int x,int y,int n)
    {
    	for (int i=0;i<=n;i++) f[i]=i;
    	for (int i=0;i<3;i++)
    		for (int j=a[x][i];j<=n;j++)
    		f[j]=max(f[j],f[j-a[x][i]]+a[y][i]);
    	return f[n];
    }//有n元钱 从x买入 y卖出 最后最多能剩多少 
    signed main()
    {
    	n=read();
    	for (int i=0;i<2;i++)
    		for (int j=0;j<3;j++)
    		a[i][j]=read();
    	cout<<solve(1,0,solve(0,1,n));
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
     
    

      E:设f[i][j]为最大数是i且有j个时的方案数,尴尬的是转移需要用到最小值数量,并且无法记录。但注意到从最小值中挑一个和把一个数变成最大值之一的过程是一一对应的,所以在新增最大值时直接将贡献乘进去即可。那么上面的dp容易得到f[i][j]=f[i][j-1]*j,于是只要记录f[i][1]并转移。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 1000010
    #define P 1000000007
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,h,d,f[N],sum[N],s,t;
    int ksm(int a,int k)
    {
    	int s=1;
    	for (;k;k>>=1,a=1ll*a*a%P) if (k&1) s=1ll*s*a%P;
    	return s;
    }
    int inv(int a){return ksm(a,P-2);}
    signed main()
    {
    	n=read(),h=read(),d=read();
    	s=t=1;
    	for (int i=2;i<=n;i++)
    	{
    		t=1ll*t*i%P;
    		s=(s+t)%P;
    	}
    	f[0]=inv(s);sum[0]=f[0];
    	for (int i=1;i<=h;i++)
    	{
    		int u=(sum[i-1]-(i>d?sum[i-d-1]:0)+P)%P;
    		f[i]=1ll*u*s%P;
    		sum[i]=(sum[i-1]+f[i])%P;
    	}
    	for (int i=n;i>=1;i--) f[h]=1ll*f[h]*i%P;
    	cout<<f[h];
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }

      result:rank 98 rating +38

  • 相关阅读:
    Linux常用软件 分类: arm-linux-Ubuntu 2013-07-22 16:28 301人阅读 评论(0) 收藏
    Linux系统信息查看命令大全 分类: arm-linux-Ubuntu 2013-07-22 16:28 302人阅读 评论(0) 收藏
    解决VC6下调不出MSDN的问题! 分类: VC++ 2013-07-22 16:28 297人阅读 评论(0) 收藏
    Shell编程基础 分类: arm-linux-Ubuntu 2013-07-22 16:28 189人阅读 评论(0) 收藏
    linux内核体系结构 分类: arm-linux-Ubuntu 2013-07-22 16:28 359人阅读 评论(0) 收藏
    Linux分区和挂载(mount命令的学习) 分类: arm-linux-Ubuntu 2013-07-22 16:28 265人阅读 评论(0) 收藏
    重新编译Linux内核必要性及其准备工作 分类: arm-linux-Ubuntu 2013-07-22 16:28 288人阅读 评论(0) 收藏
    ubuntu11.04启动 及虚拟文件系统 分类: arm-linux-Ubuntu 2013-07-22 16:28 369人阅读 评论(0) 收藏
    VxWorks 任务 分类: vxWorks 2013-07-22 16:28 646人阅读 评论(0) 收藏
    vxWorks 命令 分类: vxWorks 2013-07-22 16:28 544人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/Gloid/p/11031179.html
Copyright © 2011-2022 走看看