第四届福建省ACM程序设计大赛解题报告(未完待续)

181 篇文章 0 订阅
173 篇文章 3 订阅


Link:http://acm.fafu.edu.cn/problemList.php?volume=6   


Problem1557~1572

Hearthstone
Time Limit:1000MSMemory Limit:65536KB
Total Submissions:63Accepted:28
Share
Description:
      Cdfpysw loves playing a card game called "Hearthstone". 
      Now he has N cards, he wants to split these cards into 4 piles. Let's assume the number of cards in each pile is a1, a2, a3, a4. 
      It must be satisfied that: 
       a1 * k1 = a2 + a3 + a4 
       a2 * k2 = a1 + a3 + a4 
       a3 * k3 = a1 + a2 + a4 
       a1, a2, a3, a4 must be positive 
      Because Cdfpysw is clever, there must be a way to split there card. Can you tell Cdfpysw what is the way?
Input:
The first line is an integer T, means the number of cases. 
      Then T lines, each line contains 4 integers, N, k1, k2, k3, meaning of these have been shown in the description. 
      T <= 100 
      1 <= N <= 10^9 
      1 <= k1, k2, k3 <= 200 
      
Output:
For each case, you should output "Case #i: " first, i is the case number. 
      Then output 4 integers a1, a2, a3, a4, represent the number of cards in each pile. 
      
Sample Input:
1120 2 3 4
Sample Output:
Case #1: 40 30 24 26
编程思想:推公式。

 解以下方程组:

a1 * k1 = a2 + a3 + a4 .............(1)
        a2 * k2 = a1 + a3 + a4 .............(2)
        a3 * k3 = a1 + a2 + a4 .............(3)

a1 + a2 + a3 + a4 = n  .............(4)

      将(4)式变形后分别代入(1)(2)(3)式子可得:

a1=n/(k1+1);
a2=n/(k2+1);
a3=n/(k3+1);

a4=n-a1-a2-a3;

      然后代入输入的数据即可。


AC code:

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
	int a1,a2,a3,a4,k1,k2,k3,n,T,cas;
	scanf("%d",&T);
    for(cas=1;cas<=T;cas++)
	{
		scanf("%d%d%d%d",&n,&k1,&k2,&k3);
		a1=n/(k1+1);
		a2=n/(k2+1);
		a3=n/(k3+1);
		a4=n-a1-a2-a3;
		printf("Case #%d: %d %d %d %d\n",cas,a1,a2,a3,a4);
	}
	return 0;
}


Bilibili
Time Limit:1000MSMemory Limit:65536KB
Total Submissions:102Accepted:23
Share
Description:
      Cdfpysw loves to watch videos at bilibili.com. 
      When he watch videos, he can write some comments, and they will be shown on his screen. 
      His screen has size of n * m, and every word has size of 1 * 1. When Cdfpysw send a comment, it'll be shown on the rightmost of the topmost line which doesn't contain any comment. If there are comments in all lines, this comment will be failed to send. Every second, the comments on the screen will be shifted to left for 1 before the new comments be send. 
      e.g.: 
      Now, the following picture is the screen. Cdfpysw wants to write 3 comments at now, 1 second later, and 6 seconds later. They will be shown on the 2nd line, 5th line, and 1st line. 
        
      This example is NOT same as the sample below! 
      Now Cdfpysw wants to know his comments would be shown on which line, if the comment is failed to send, print "Failed!". 
      
Input:
The first line is an integer T, means the number of cases. 
      For each case 
       The first line contains 3 integers, n, m, q, means the size of screen and the number of comments Cdfpysw wants to send. 
       Then q lines, for each line, there are 2 integers t, l, means the sending time and the length of the comment. It is guaranteed that t is in ascending order. 
      T <= 10 
      1 <= n, m, q <= 50000 
      0 <= t <= 10^9 
      1 <= l <= 10^9 
      
Output:
For each case, you should print "Case #i:" in a line, i is the case number. 
      Then q lines, each line contains an integer to represent the line to show the comment or a string "Failed!" to represent the comment is failed to send. 
      
Sample Input:
15 5 70 34 37 58 19 1010 511 5
Sample Output:
Case #1:123145Failed!`

编程思想:贪心。比赛时直接暴力模拟就过了,但赛后提交却TLE,必须采用STL的set集合实现nlog(n)的时间复杂度才能过。。


TLE  code:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
int row[50050];
int t1,t,n,m,q,l;
int main()
{
	//freopen("D:\in.txt","r",stdin);

	int T,cas,i,fg,ans;
	scanf("%d",&T);
	cas=0;
	while(T--)
	{
		cas++;
		printf("Case #%d:\n",cas);
		scanf("%d%d%d",&n,&m,&q);
		memset(row,0,sizeof(row));
		t1=0;
		while(q--)
		{
			scanf("%d%d",&t,&l);
			l+=m;
			fg=0;
			for(i=1;i<=n;i++)
			{
				row[i]-=(t-t1);
			    if(row[i]<=0)
			    {
			    	row[i]=0;
			    	if(!fg)
			    	{
			    		fg=i;
						printf("%d\n",fg);
						row[i]=l;
					}
				}	
			}
			t1=t;
			if(!fg) printf("Failed!\n");
		}
	}
	return 0;
 } 


AC code:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<queue>
#include<map>
#include<set>
#define LL long long
using namespace std;
int row[50050];
struct node{
	int finish;
	int id;
	bool operator < (const node &a)const{
		if(finish!=a.finish) return finish<a.finish;
		else return id<a.id;
	}
};
set<node>s;
set<node>::iterator it;
set<int>ss;
set<int>::iterator it2;
node p1;
int t,n,m,q,l,cnt;
int main()
{
	//freopen("D:\in.txt","r",stdin);
	int T,cas,i;
	scanf("%d",&T);
	cas=0;
	while(T--)
	{
		cas++;
		printf("Case #%d:\n",cas);
		scanf("%d%d%d",&n,&m,&q);
		cnt=0;
		s.clear();
		ss.clear();
		while(q--)
		{
			scanf("%d%d",&t,&l);
			it=s.begin();
			while(it!=s.end())
			{
				if((*it).finish<=t)
				{
					ss.insert((*it).id);
					set<node>::iterator it1=it;
					s.erase(it1);
					it++;
				}
				else break;
			}
			if(ss.empty())
			{
				++cnt;
				if(cnt>n)
					printf("Failed!\n");
				else
				{
					printf("%d\n",cnt);
					p1.finish=t+l+m;
					p1.id=cnt;
					s.insert(p1);
				}
			}
			else
			{
				it2=ss.begin();
				printf("%d\n",*it2);
				p1.finish=t+l+m;
				p1.id=*it2;
				s.insert(p1);
				ss.erase(*it2);
			}
		}
	}
	return 0;
 } 


Triangle
Time Limit:1000MSMemory Limit:65536KB
Total Submissions:115Accepted:36
Share
Description:
      This is a simple question, give you a triangle, please divide the triangle into two parts with a segment. 
      These two parts should have the same area, and the segment should be as short as possible. Please calculate the length of the segment. 
      
Input:
The first line of the input is the number T(T<=100), which is the number of cases followed. 
      For each test case, the only line contains space-separated integers x1, y1, x2, y2, x3, y3,the coordinates of triangle endpoint. 
      The absolute value of all the coordinates will not be more than 10^9. 
      
Output:
For each test case, output only one line, containing the length of segment only. Your answer should be rounded to 4 digits after the decimal point
Sample Input:
10 0 10 0 0 10
Sample Output:
6.4359

编程思想:推公式。所求的最短边将原三角形最长和次长边截成一个面积为原三角形一半的等腰三角形的两条腰,剩下的就是利用三角形面积公式和余弦定理推出公式来。详见AC代码。


AC code:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<math.h>
#include<cstring>
#include<queue>
#include<map>
#include<set>
#define LL long long
using namespace std;

double dis(double x1,double y1,double x2,double y2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

int main()
{
	double a,b,c,x1,y1,x2,y2,x3,y3,ans;
	//freopen("D:\in.txt","r",stdin);
	int T,cas,i;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3);
		a=dis(x1,y1,x2,y2);
		b=dis(x2,y2,x3,y3);
		c=dis(x3,y3,x1,y1);
		if(b<c) swap(b,c);//使c为三角形的最短边
		if(a<c) swap(a,c);
		ans=sqrt(a*b-0.5*(a*a+b*b-c*c));
		printf("%.4f\n",ans);
	}
	return 0;
 } 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

林下的码路

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

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

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

打赏作者

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

抵扣说明:

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

余额充值