【复盘】7.20训练:UCF Local Programming Contest Round 1A

地址

A-Briefcases Full of Money

A

题意:
有面值为1,5,10,20,50,100的钱,按顺序输入它们的个数,输出个数最大的面值。

读懂就AC:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=7;
struct node
{
	int money,num;
	int ans;
};
int cmp(node a,node b)
{
	if(a.ans!=b.ans) return a.ans>b.ans;
	else return a.num<b.num;
}
int main()
{
	//1 5 10 20 50 100
	node a[N];
	for(int i=1;i<=6;i++)
	{
		cin>>a[i].num;
	}
	for(int i=1;i<=6;i++)
	{
		if(i==1) a[i].money=1;
		else if(i==2) a[i].money=5;
		else if(i==3) a[i].money=10;
		else if(i==4) a[i].money=20;
		else if(i==5) a[i].money=50;
		else a[i].money=100;
	}
	for(int i=1;i<=6;i++)
	{
		a[i].ans=a[i].money*a[i].num;
	}
	sort(a+1,a+7,cmp);
	cout<<a[1].money;
	return 0; 
}

B-A Game Called Mind

B

题意:
p个人,第一个是A,第二个是B…以此类推。
后p行先输入n,表示n个数字,后输入a[n];按数子从小到大顺序排AB顺序。

如:

输入:
2 
3 10 40 50
2 20 30
输出:
ABBAA
输入:
3 
4 40 51 60 70
3 12 32 42
5 20 53 80 90 95
输出:
BCBABACAACCC

最小的是12,是B的。

读懂即AC。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=105;
struct node
{
	char op;
	int val;
};
int cmp(node a,node b)
{
	return a.val<b.val;
}
int main()
{
	int n;cin>>n;
	node a[100];
	int temp=0;
	int chh=0;
	while(n--)
	{
		int t;
		cin>>t;
		for(int i=0;i<t;i++)
		{
			a[temp].op='A'+chh;
			cin>>a[temp++].val;			
		}
		chh++;
	}
//	//show
//	for(int i=0;i<temp;i++)
//	{
//		cout<<a[i].op<<" "<<a[i].val<<endl;
//	}
	sort(a,a+temp,cmp);
	for(int i=0;i<temp;i++)
	{
		cout<<a[i].op;
	}
	return 0; 
}

C-Unique Values

C
题意:给一串数字,输出连续的、数字不相同的,字串的个数。

双指针问题,要注意开始的位置。如,字串最后的数字是2,那么开始的位置就是上一个数字为2的位置的下一位。加上这一字串的长度即为这次可以组成的字串个数。

如样例2:
输入:

8 
2 12 3 12 3 2 6 9

对2 12 3可以有的字串个数:1+2+3=6;
对2 12 3 12:即为3 12,个数为2;前面的就直接删掉了,相当于“开始指针”往后移。
对2 12 3 12 3:即12 3,个数为2,开始指针移到第4位了。
对2 12 3 12 3 2 6 9,即为12 3 2 6 9,个数为3+4+5=12;(从数字2开始算,不然与上面的重复了)。
ans=6+2+2+12=22;

核心:
但凡出现重复数字,从当时l一直往前加,b[]的个数一直减,当出现b[a[i]]==1时,说明重复数字及前面的数字(个数)已经被减掉,l指向最后一个重复数字的下一位,即更新了“开始指针”

while(b[a[i]]>1)
{
	b[a[l]]--;
	l++;
}

注意,这里要用map,不能开两个数组,因为b[a[i]],a[i]范围是LL的。b会爆。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
ll a[N];
//双指针,一个是开始指向的l,一个是当前指向的i 
int main()
{
	ios::sync_with_stdio(false);
	int n;cin>>n;
	ll ans=0;
	int l=1;
	map<ll,int>b;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		b[a[i]]++;
		while(b[a[i]]>1)
		{
			b[a[l]]--;
			l++;
		}
		ans+=(i-l+1);
	}
	cout<<ans;
	return 0; 
}

D-Gone Fishing

D

题意:
输入渔网半径r,鱼的数量n,后n行输入鱼的坐标。求一个渔网能捕到的最多的鱼。

当存在两条鱼正好在渔网上时,这个渔网是最优的。
即,用两个坐标算出圆心的坐标。
注意:每个渔网最少能捕到的鱼为1条。

核心:已知两点求圆心:

node center(node aa,node bb)
{
	node t;//中点 
	t.x=(aa.x+bb.x)/2.0;
	t.y=(aa.y+bb.y)/2.0;
	double temp=dis(aa,t);
	double h=sqrt(r*r-temp*temp);
	node c;
	double jiao=-1*atan2((aa.x-bb.x),(aa.y-bb.y));
	c.x=t.x+h*cos(jiao);
	c.y=t.y+h*sin(jiao);
	return c;
}

其中,atan2函数:

int x,y;cin>>x>>y;
double a=atan2(y,x);
cout<<sin(a);

输入1 2,输出的值为2/sqrt(5);即atan2(y,x)所求的角的对边为y;
感觉没太搞清楚…几个参考资料:
atan(y/x)与atan2(y,x)的区别
atan2相关知识汇总

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=105;
const double pi=acos(-1.0);
const double eps=1e-6;
int r;
struct node
{
	double x,y;	
};
node a[N];
double dis(node aa,node bb)//两点间距离 
{
	double ans=sqrt((aa.x-bb.x)*(aa.x-bb.x)+(aa.y-bb.y)*(aa.y-bb.y));
	return ans;
}
node center(node aa,node bb)
{
	node t;//中点 
	t.x=(aa.x+bb.x)/2.0;
	t.y=(aa.y+bb.y)/2.0;
	double temp=dis(aa,t);
	double h=sqrt(r*r-temp*temp);
	node c;
	double jiao=-1*atan2((aa.x-bb.x),(aa.y-bb.y));
	c.x=t.x+h*cos(jiao);
	c.y=t.y+h*sin(jiao);
	return c;
}
int main()
{
	ios::sync_with_stdio(false);
	cin>>r;
	int n;cin>>n;
	for(int i=0;i<n;i++)  cin>>a[i].x>>a[i].y;
	
	int ans=1;
	for(int i=0;i<n-1;i++)
	{
		node cen;//圆心 
		for(int j=i+1;j<n;j++)
		{
			//atan(y,x)求的是角度,此角度的对边为y 
			cen=center(a[i],a[j]);
			int anst=0;
			for(int k=0;k<n;k++)
			{
				if(dis(cen,a[k])-r<=eps) anst++;
			}
			ans=max(ans,anst);
		}
	}
	cout<<ans;
	return 0; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

karshey

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值