第六届福建省大学生程序设计竞赛(几道水题)

FZU2212:http://acm.fzu.edu.cn/problem.php?pid=2212

水题

#include<stdio.h>
#include<iostream> 
#include <algorithm>
#include<string.h>
#include<vector>
#include<math.h>
#include<queue>
#include<deque>
#include<set>
#define ll long long
#define INF 0x3f3f3f3f
const int  mod = 1e9+7;
using namespace std;
int KGCD(int a,int b){if(a==0)return b;if(b==0)return a;if(~a&1){ if(b&1) return KGCD(a>>1,b);else return KGCD(a>>1,b>>1) <<1; } if(~b & 1)  return KGCD(a, b>>1);  if(a > b) return KGCD((a-b)>>1, b);return KGCD((b-a)>>1, a);}  
int LCM(int a,int b){ return a/KGCD(a,b)*b; } 
inline ll qpow(ll n,ll m){n%=mod;ll ans=1;while(m){if(m%2) ans=(ans*n)%mod;m/=2;n=(n*n)%mod;}return ans;}
inline ll inv(ll b){return b==1?1:(mod-mod/b)*inv(mod%b)%mod;}
inline ll inv2(ll b){return qpow(b,mod-2);}
int dir[5][2]={0,1,0,-1,1,0,-1,0};
using namespace std;
int map[150];
int main()
{
	int T,n,m,temp;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		for(int i=0;i<n;i++)
		{
			scanf("%d",&temp);
			temp=100-temp;
			map[i]=temp;
		}
		sort(map,map+n);
		int count=0;
		for(int i=0;i<n;i++)
		{
			if(m>=map[i])
			{
				count++;
				m=m-map[i];
			}
			else 
				break;
		}
		printf("%d\n",count);
	}
	return 0;
}

FZU2213:http://acm.fzu.edu.cn/problem.php?pid=2213

题意: 给你两个圆的位置和半径,求有多少条同时对两个圆都相切的直线  如果大圆套小圆输出-1

#include<stdio.h>
#include<iostream> 
#include <algorithm>
#include<string.h>
#include<vector>
#include<math.h>
#include<queue>
#include<deque>
#include<set>
#define ll long long
#define INF 0x3f3f3f3f
const int  mod = 1e9+7;
using namespace std;
int KGCD(int a,int b){if(a==0)return b;if(b==0)return a;if(~a&1){ if(b&1) return KGCD(a>>1,b);else return KGCD(a>>1,b>>1) <<1; } if(~b & 1)  return KGCD(a, b>>1);  if(a > b) return KGCD((a-b)>>1, b);return KGCD((b-a)>>1, a);}  
int LCM(int a,int b){ return a/KGCD(a,b)*b; } 
inline ll qpow(ll n,ll m){n%=mod;ll ans=1;while(m){if(m%2) ans=(ans*n)%mod;m/=2;n=(n*n)%mod;}return ans;}
inline ll inv(ll b){return b==1?1:(mod-mod/b)*inv(mod%b)%mod;}
inline ll inv2(ll b){return qpow(b,mod-2);}
int dir[5][2]={0,1,0,-1,1,0,-1,0};
using namespace std;
int main()
{
	int n;
	double a,b,c,d,e,f;
	scanf("%d",&n);
	while(n--)
	{
		scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f);
		double x=(a-d)*(a-d);
		double x1=(b-e)*(b-e);
		double x2=(double)sqrt(x+x1);
		if((a==d) &&(b==e) && (c==f) )
			printf("-1\n");
		else
		{
			if(x2>(c+f))
				printf("4\n");
			else if(x2==(c+f))
				printf("3\n");
			else if(x2==(max(c,f)-min(f,c)))
				printf("1\n");
			else if(x2<(max(c,f)-min(f,c)))
				printf("0\n");
			else
				printf("2\n");
		}
	}
	
	return 0;
}
FZU 2214 :http://acm.fzu.edu.cn/problem.php?pid=2214
动态规划 背包问题  
给你个背包,给你最大承重,求最大承重范围内,包内物品的最大价值。

枚举价值:

#include<stdio.h>
#include<iostream> 
#include <algorithm>
#include<string.h>
#include<vector>
#include<math.h>
#include<queue>
#include<deque>
#include<set>
#define ll long long
#define INF 0x3f3f3f3f
const int  mod = 1e9+7;
using namespace std;
int KGCD(int a,int b){if(a==0)return b;if(b==0)return a;if(~a&1){ if(b&1) return KGCD(a>>1,b);else return KGCD(a>>1,b>>1) <<1; } if(~b & 1)  return KGCD(a, b>>1);  if(a > b) return KGCD((a-b)>>1, b);return KGCD((b-a)>>1, a);}  
int LCM(int a,int b){ return a/KGCD(a,b)*b; } 
inline ll qpow(ll n,ll m){n%=mod;ll ans=1;while(m){if(m%2) ans=(ans*n)%mod;m/=2;n=(n*n)%mod;}return ans;}
inline ll inv(ll b){return b==1?1:(mod-mod/b)*inv(mod%b)%mod;}
inline ll inv2(ll b){return qpow(b,mod-2);}
int dir[5][2]={0,1,0,-1,1,0,-1,0};
using namespace std;
struct node{
	int W;
	int V;
}nn[1000];
int dp[5050];
int main()
{
	int t,n;
	int b;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&b);
		int sum=0;
		for(int i=0;i<n;i++)
		{
			scanf("%d%d",&nn[i].W,&nn[i].V);
			sum=sum+nn[i].V;
		}
		for(int i=1;i<=sum;i++)
			dp[i]=INF;
		dp[0]=0;
		for(int i=0;i<n;i++)
		{
			for(int j=sum;j>=nn[i].V;j--)//枚举价值 
			{
				if(dp[j-nn[i].V]!=INF)//存放重量 
				{
					dp[j]=min(dp[j],dp[j-nn[i].V]+nn[i].W);//求出来当前价值最小的重量是多少 
				}
			}
		}
		for(int i=sum;i>=0;i--)
		{
			if(dp[i]<=b)
			{
				printf("%d\n",i);
				break;
			}
		}
	}
	return 0;
}
枚举物品
#include<stdio.h>
#include<iostream> 
#include <algorithm>
#include<string.h>
#include<vector>
#include<math.h>
#include<queue>
#include<deque>
#include<set>
#define ll long long
#define INF 0x3f3f3f3f
const int  mod = 1e9+7;
using namespace std;
int KGCD(int a,int b){if(a==0)return b;if(b==0)return a;if(~a&1){ if(b&1) return KGCD(a>>1,b);else return KGCD(a>>1,b>>1) <<1; } if(~b & 1)  return KGCD(a, b>>1);  if(a > b) return KGCD((a-b)>>1, b);return KGCD((b-a)>>1, a);}  
int LCM(int a,int b){ return a/KGCD(a,b)*b; } 
inline ll qpow(ll n,ll m){n%=mod;ll ans=1;while(m){if(m%2) ans=(ans*n)%mod;m/=2;n=(n*n)%mod;}return ans;}
inline ll inv(ll b){return b==1?1:(mod-mod/b)*inv(mod%b)%mod;}
inline ll inv2(ll b){return qpow(b,mod-2);}
int dir[5][2]={0,1,0,-1,1,0,-1,0};
using namespace std;
int dp[502][5005]; 
int w[505];
int v[505];
int main()
{
	int t,n,m,sum, totalValue;
	scanf("%d",&t);
	while(t--)
	{
		sum=totalValue = 0;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)
		{
			scanf("%d%d",&w[i],&v[i]);
			sum=sum+v[i];
		}
		memset(dp,INF,sizeof(dp));
		dp[0][0]=0;
		for(int i=1;i<=n;i++)
		{
			dp[i][0]=0;
			for(int j=0;j<=sum;j++)
			{
				if(j>=v[i])
					dp[i][j]=min(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);
				else
					dp[i][j]=dp[i-1][j];
			//	printf("%d  %d  %d\n",i,j,dp[i][j]);
			}	
		}
		for(int i=sum;i>=0;i--)
		{
			if(dp[n][i]<=m) {
				totalValue = i;
				break;
			}
		}
		printf("%d\n", totalValue);
	}
	return 0;
}

FZU 2216 :http://acm.fzu.edu.cn/problem.php?pid=2216

给你一堆卡牌,然后给你几张王牌(可以作为1-m的任何一张卡),求递增的连续序列的最长长度

#include<stdio.h>
#include<iostream> 
#include <algorithm>
#include<string.h>
#include<vector>
#include<math.h>
#include<queue>
#include<deque>
#include<set>
#define ll long long
#define INF 0x3f3f3f3f
const int  mod = 1e9+7;
using namespace std;
int KGCD(int a,int b){if(a==0)return b;if(b==0)return a;if(~a&1){ if(b&1) return KGCD(a>>1,b);else return KGCD(a>>1,b>>1) <<1; } if(~b & 1)  return KGCD(a, b>>1);  if(a > b) return KGCD((a-b)>>1, b);return KGCD((b-a)>>1, a);}  
int LCM(int a,int b){ return a/KGCD(a,b)*b; } 
inline ll qpow(ll n,ll m){n%=mod;ll ans=1;while(m){if(m%2) ans=(ans*n)%mod;m/=2;n=(n*n)%mod;}return ans;}
inline ll inv(ll b){return b==1?1:(mod-mod/b)*inv(mod%b)%mod;}
inline ll inv2(ll b){return qpow(b,mod-2);}
int dir[5][2]={0,1,0,-1,1,0,-1,0};
using namespace std;
int tt[100005];
int tt1[100005];
int main()
{
	int t,n,m,zero,temp;
	scanf("%d",&t);
	while(t--)
	{
		memset(tt,0,sizeof(tt));
		zero=0;
		scanf("%d%d",&n,&m);
		for(int i=0;i<n;i++)
		{
			scanf("%d",&temp);
			if(temp==0)
				zero++;
			else
			{
				tt[temp]=1;
			}
		}
		tt1[0]=0;
		for(int i=1;i<=m;i++)//看看i-m每个点之前需要有多少0 
		{
			if(tt[i])
				tt1[i]=tt1[i-1];//需要0的个数 
			else
				tt1[i]=tt1[i-1]+1;	
		}
		int MAX=0; 
		for(int i=0;i<=m;i++)//2分 
		{
			int l=i;
			int r=m;
			int mid;
			while(l<=r)
			{
				mid=(l+r)/2;
				if(tt1[mid]-tt1[i]>zero)
					r=mid-1;
				else
					l=mid+1;
			}
			MAX=max(MAX,r-i);//自我体会 mid 和 r 的差别
		}
		printf("%d\n",MAX);
		
	}
	return 0;
}

FZU 2221 :http://acm.fzu.edu.cn/problem.php?pid=2221

就是两边群殴,只要你人多就赢, 如果相同 RUN MAN win 
如果有极端大 肯定会有极端小 这样不是最优的 
最优的是均分,只要和比最小的两个的和大2就说明肯定能赢。
#include<stdio.h>
#include<iostream> 
#include <algorithm>
#include<string.h>
#include<vector>
#include<math.h>
#include<queue>
#include<deque>
#include<set>
#define ll long long
#define INF 0x3f3f3f3f
const int  mod = 1e9+7;
using namespace std;
int KGCD(int a,int b){if(a==0)return b;if(b==0)return a;if(~a&1){ if(b&1) return KGCD(a>>1,b);else return KGCD(a>>1,b>>1) <<1; } if(~b & 1)  return KGCD(a, b>>1);  if(a > b) return KGCD((a-b)>>1, b);return KGCD((b-a)>>1, a);}  
int LCM(int a,int b){ return a/KGCD(a,b)*b; } 
inline ll qpow(ll n,ll m){n%=mod;ll ans=1;while(m){if(m%2) ans=(ans*n)%mod;m/=2;n=(n*n)%mod;}return ans;}
inline ll inv(ll b){return b==1?1:(mod-mod/b)*inv(mod%b)%mod;}
inline ll inv2(ll b){return qpow(b,mod-2);}
int dir[5][2]={0,1,0,-1,1,0,-1,0};
using namespace std;
int main()
{
	int n;
	int a,b,sum;
	scanf("%d",&n);
	while(n--)
	{
		scanf("%d%d",&a,&b);
		int w=a/3;
		int c=a%3;
		if(c==2)
			sum=w+w+1;
		else
			sum=w+w;
		sum=sum+2;
		if(sum > b)
			printf("Yes\n");
		else
			printf("No\n"); 
	}
	return 0; 
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值