算法课作业1

发布于:2023-09-16 ⋅ 阅读:(71) ⋅ 点赞:(0)

https://vjudge.net/contest/581138

A - Humidex

模拟题

题目大意

给三个类型数字通过公式来回转化

思路

求e的对数有log函数,不懂为什么不会出精度错误,很迷,给的三个数字也没有顺序,需要多判断。

#include<cstdio>
#include<iostream>
#include<cmath>
//Sometimes weather reports give the temperature and dewpoint,
// or the temperature and humidex
/*
D 15.0 H 34.0
D 25.0 H 42.3
E
*/
using namespace std;
int main()
{
	char a,b;
	double a1,b1;
	while(1)
	{
		cin>>a;
		if(a=='E')
			break;
		cin>>a1>>b>>b1;

		if(a=='T'&&b=='D'||a=='D'&&b=='T')
		{ 
			if(a=='D'&&b=='T')
				swap(a1,b1);
			double e=6.11*(pow(2.718281828,5417.7530*((1/273.16)-(1/(b1+273.16)))));
			double h=0.5555*(e-10.0);
			double humidex = a1+h;
			printf("T %.1lf D %.1lf H %.1lf\n",a1,b1,humidex);
		}
		else if(a=='T'&&b=='H'||a=='H'&&b=='T')
		{
			if(a=='H'&&b=='T')
				swap(a1,b1);
			double dewpoint;
			double h=b1-a1;
			double e=h/0.5555+10.0;
			double x=log(e/6.11)/5417.753;
			dewpoint=1/(1/273.16-x)-273.16;
			printf("T %.1lf D %.1lf H %.1lf\n",a1,dewpoint,b1);
		}
		else // d h
		{
			if(a=='H'&&b=='D')
				swap(a1,b1);
			double e=6.11*pow(2.718281828,5417.7530*((1/273.16)-(1/(a1+273.16))));
			double h=(0.5555)*(e - 10.0);
			double temperature=b1-h;
			printf("T %.1lf D %.1lf H %.1lf\n",temperature,a1,b1);
		}
	}


}

B - Moving Tables

题目大意

两排都是房间,一排两百个房间,上面按奇数,下面按偶数编号,之后房间两两之间要搬桌子,搬桌子期间中间通道全部占用,可同步进行,搬一次10分钟,求最小时间

思路

就把中间通道编号,奇数和偶数的编号调成1-200,之后对区间进行累加,重合次数最多的就是最小时间。注意坑就是,区间不一样从小到大,l,r要判断一下大小。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
int box[205];
/*
3
4
10 20
30 40
50 60
70 80
2
1 3
2 200
3
10 100
20 80
30 50
*/
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		cin>>n;
		memset(box,0,sizeof(box));
		int maxx=0;
		for(int i=1; i<=n; i++)
		{
			int l,r;
			cin>>l>>r;
			if(l%2==1)
				l=l+1;
			if(r%2==1)
				r=r+1;
			l=l/2;
			r=r/2;
			if(l>r)
				swap(l,r);
			for(int j=l; j<=r; j++)
			{
				box[j]++;
				maxx=max(box[j],maxx);
			}
		}
		printf("%d\n",maxx*10);

	}

}

C - Counterfeit Dollar

题意

有12个硬币,现在知道其中有一个假的,已知称三次天平可以找出来假硬币,假硬币有可能轻或重,每次给三组称量结果,求出哪个是硬币,是轻是重。

思路

好丑陋的代码,不懂为啥我写的这么长,思路不太好吧,我的思路就是去暴力枚举每一个假硬币,并且枚举它是轻的假还是重的假,用box数组记录每次天平上各个位置的重量,真硬币就算重量1,假轻硬币就重量0,假重硬币就重量10,最后判断,找出来就行,模拟题,写的是真费劲,OJ还不支持string 用的char还查了一堆函数,费劲,代码能力现在下降严重。

#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
/*
1
ABCDEF GHIJKL up 
ABC DEF even 
I J down 
*/
int box[20];
int main()
{
	int n;
	cin>>n;
	while(n--)
	{
		char a[3][15],b[3][15],c[3][15];
		memset(box,0,sizeof(box));
		for(int i=0; i<3; i++)
		{
			scanf("%s %s %s",a[i],b[i],c[i]);
			strcat(a[i],b[i]);
		}
		for(int i=1; i<=12; i++) // 枚举每个都是假币
		{
			char x='A'+i-1;
			// 假币轻
			int flagt=0;
			int pos,lenn;
			char t[20];
			for(int j=0; j<3; j++)
			{
				memset(box,0,sizeof(box));
				int len=strlen(a[j]);
				for(int k=0; k<len; k++)
				{
					if(a[j][k]!=x)
						box[k]++;
					if(a[j][k]==x)
					{
						pos=k;
						lenn=len;
//						t=c[j];
						strcpy(t,c[j]);
					}
				}
				int box1=0,box2=0;
				for(int k=0; k<len/2; k++)
					box1+=box[k];
				for(int k=len/2; k<len; k++)
					box2+=box[k];
				
				if(strcmp(c[j],"even")==0&&box1==box2) flagt++;
				if(strcmp(c[j],"up")==0&&box1>box2) flagt++;
				if(strcmp(c[j],"down")==0&&box1<box2) flagt++;
//				printf("%d %d %c %d len=%d\n",box1,box2,x,flagt,len);
			}

			//假币重
			if(flagt!=3)
			{
				flagt=0;
				for(int j=0; j<3; j++)
				{
					memset(box,0,sizeof(box));
					int len=strlen(a[j]);
					for(int k=0; k<len; k++)
					{
						if(a[j][k]!=x)
							box[k]++;
						if(a[j][k]==x)
						{
							box[k]+=10;
							pos=k;
							lenn=len;
//							t=c[j];
							strcpy(t,c[j]);
						}
					}
					int box1=0,box2=0;
					for(int k=0; k<len/2; k++)
						box1+=box[k];
					for(int k=len/2; k<len; k++)
						box2+=box[k];
					if(strcmp(c[j],"even")==0&&box1==box2) flagt++;
					if(strcmp(c[j],"up")==0&&box1>box2) flagt++;
					if(strcmp(c[j],"down")==0&&box1<box2) flagt++;
				}
			}
			if(flagt==3)
			{
				if(pos<lenn/2)
				{
					if(strcmp(t,"up")==0)
						printf("%c is the counterfeit coin and it is heavy.\n",x);
					else
						printf("%c is the counterfeit coin and it is light.\n",x);
				}
				else
				{
					if(strcmp(t,"up")==0)
						printf("%c is the counterfeit coin and it is light.\n",x);
					else
						printf("%c is the counterfeit coin and it is heavy.\n",x);
				}
				break;
			}
		}
	}

}

D - Radar Installation

题目大意

雷达部署在x轴,给出半径,陆地在任意位置,现在已知所有陆地位置,要求使用最少雷达覆盖所有陆地。

思路

以每个陆地为圆心画圆,交x轴出现线段,线段长度即为这个陆地所需要的雷达区间,对每个陆地转化为一个线段,将线段按右端点排序,之后从左往右遍历线段,每次呢取端点的最右端作为雷达,下一个线段出现左端点在雷达左右两边的情况,在左边呢就不用管,在右边呢就更新右端点为新的雷达。
这个题,输入格式好奇怪,我觉得是个错题。思路对了,照着别的代码硬改出来。为什么n=0能过?不应该n0&&d0吗?

#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;

struct node
{
	double l,r;
} a[1005];
int cmp(node a,node b)
{
	return a.r<b.r;
}
int main()
{
	int cnt=0;
	int n;double d;
	while(scanf("%d%lf",&n,&d))
	{
		cnt++;
		if(n==0) break;
		int flag=0;
		for(int i=1; i<=n; i++)
		{
			double x,y;
			scanf("%lf%lf",&x,&y);
//			if(d<y||d<=0)
			if(d<y||d<=0)
			{
				flag=1;
				continue;
			}
			double c=sqrt(1.0*d*d-1.0*y*y);
			a[i].l=(double)x-c;
			a[i].r=(double)x+c;
//			printf("%lf %lf\n",a[i].l,a[i].r);
		}
		if(flag==1)
		{
			printf("Case %d: -1\n",cnt);
			continue;
		}
		sort(a+1,a+1+n,cmp);
		int ans=0;
		double pos=-100000000;
		for(int i=1; i<=n; i++)
		{
			if(pos<a[i].l)
			{
				pos=a[i].r;
				ans++;
			}
		}
		printf("Case %d: %d\n",cnt,ans);
	}
}

H - Cow Bowling

题目大意

从顶点往下向左或向右,走到最下面,找到一条累加和最大的值。

思路

数字三角形经典题

#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;

int dp[355][355];
int m[355][355];
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
			scanf("%d",&m[i][j]);
	}
	for(int i=1;i<=n;i++)
		dp[n][i]=m[n][i];
	for(int i=n-1;i>=1;i--)
		for(int j=1;j<=i;j++)
		{
			dp[i][j]=m[i][j]+max(dp[i+1][j],dp[i+1][j+1]);
		}
	printf("%d",dp[1][1]);
}


网站公告

今日签到

点亮在社区的每一天
去签到