2022.7.7暑假团队训练赛3-UCF

暑假的第三场团队训练赛,这套题做起来就感觉不是那么的顺利,出现很多问题,说明还需要继续努力啊,水平太低了。这套题虽然过来五道,但是其中大部分都是大佬写的。

A . Exact Change

题目描述

Whenever the UCF Programming Team travels to World Finals, Glenn likes having the exact amount of money necessary for any purchase, so that he doesn’t have to count and receive change. Of course, most countries don’t have many different denominations of coins, so Glenn creates different “packages” with him, each with some particular amount of money, in cents.

Glenn would like to know which amount of money (in cents), is the smallest that he can’t pay for exactly, with some combination of his packages.

The Problem:

Given a list of positive integers, determine the smallest integer that can’t be represented as the sum of some subset of the integers on the list.

输入描述

The first input line contains a single positive integer, nn (1<n≤1001<n≤100), indicating the number of sets of coin packages to evaluate. Each of the nn input sets follows. The first line of each input set contains only an integer, cc (1≤c<311≤c<31), representing the number of different packages of coin for that input set. The following line contains exactly cc positive integers, each separated by a single space, representing the value of each of the cc packages in cents. The sum of these cc integers is guaranteed not to exceed 109109. Note that the package values are not necessarily distinct, i.e., there may be multiple packages with the same value.

输出描述

For each set of packages, first output “Set #ii: ” where ii is the input data set number, starting with 1. Follow this with a single positive integer, the smallest value that can’t be represented as a sum of the values of a subset of the packages given. Note that a package value can be used at most once in a subset unless there are multiple packages with that value (if there are mm occurrences of a package value, up to mm occurrences of that value can be used in a subset).

Leave a blank line after the output for each test case. Follow the format illustrated in Sample Output.

样例输入:

3
6
12 8 1 2 4 100
3
1 2 3
6
3 1 3 2 3 3

样例输出:

Set #1: 28

Set #2: 7

Set #3: 16

题目大意:

给出n个数表示纸币的面额,每张纸币使用一次,问不能组成的最小的金额。

思路:

这个题一开始想用搜索,发现超时了,用了dp也超时了。最后思路是大佬想出来的,先进行升序排序。我设一个k,k从0开始,如果a[i] <= k+1,那我就将k+a[i],表示从1-k分别加上a[i]可以到的最大的值,这样就可以从1到这一个新的k。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[110];
int main()
{
    int t;
    cin >> t;
    for(int ii = 1;ii <= t;ii++){
        int n;
        cin >> n;
        for(int i = 0;i < n;i++){
            cin >> a[i];
        }
        sort(a,a+n);
        ll sum = 0;
        for(int i = 0;i < n;i++){
            if(a[i] <= sum+1)
                sum += a[i];
            else
                break;
        }
        cout << "Set #" << ii << ": " << sum + 1 << endl << endl;
    }
}

C . Fold the Paper Nicely (大水题)

题目描述

Dr. Orooji has a daily calendar (365 pages) on his desk. Every morning, he tears off one page and, as he is reading the notes on the next page, he folds (out of habit) the sheet in his hand. Dr. O noticed that he always folds the sheet (a rectangular paper) along the longer side, e.g., if one side is 80 and the other side is 60, he would fold along 80; this will make the paper of size 40 and 60; if he folds it again, he would fold along 60 since that’s the longer side now.

The Problem:

Given a rectangular piece of paper and how many times Dr. O folds it, you are to determine the final sizes. When folding a side with an odd length, the fraction is ignored after folding, e.g., if a side is 7, it will become 3 after folding.

输入描述

The input consists of one line, containing three positive integers (each ≤ 10000), the first two providing the rectangle sides and the third providing the number of folds.

输出描述

Print the final values for the rectangle (larger side of the final values first).

样例输入1:

60 51 4

样例输出1:

15 12

样例输入2:

3 2 50

样例输出2:

0 0

题目大意:

给出长方形的两条边,进行n次处理。每次都将最大的边除以2,问n次处理后两条边的数值是多少。

思路:

这个题目的思路很容易想到,直接循环跑就行了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a,b;
void px()
{
    if(a < b)
        swap(a,b);
}
int main()
{
    int t;
    cin >> a >> b >> t;
    px();
    while(t--){
        a /= 2;
        px();
    }
    cout << a << " " << b;
}

 F . Call Me Maybe

题目描述

The popular song, “Call Me Maybe” by Carly Rae Jepson, has been spoofed with great comedic success on the internet recently. In particular, one of the YouTube videos splices words from different speeches by President Obama to string together the lyrics of the song. You have decided that this idea is comic gold. Given a library of a particular person’s speeches as well as the lyrics to a song, you want to spoof them by writing a program to automatically check the text of all of the speeches to make the appropriate word substitutions from the speeches to the song lyrics. For example, the first line of “Call Me Maybe” is “I threw a wish in the well.” Perhaps “I” appears as the 10th word in speech number 4, “threw” appears as the 54th word in speech number 12, etc. Of course, if the speaker never said “wish” in any of his speeches, then the spoof is not possible. With your program, you can spoof almost any song with any celebrity and get rich!

The Problem:

Given a list of speeches by an individual, as well as the text of a song to spoof by pulling words from those speeches, determine if the spoof is possible and, if so, give a listing of which words in which speeches to use as substitutes.

In order to obtain a unique answer, you must cycle through each occurrence of a particular word in the set of speeches, in order by speech and word. Thus, if the word, “I” appears five times in the song and appears in the following four locations: (1) speech 2, word 7, (2) speech 4, word 12, (3) speech 4, word 50, and (4) speech 5, word 1, then the first substitution would come from speech 2, the second substitution would be the 12th word of speech 4, the third substitution would be the 50th word of speech 4, the fourth substitution would be from speech 5 and the last substitution would be from speech 2 again. As this example illustrates, a word does not have to appear in speeches as many times as it appears in a song. It does, however, have to appear at least once. Note also that a word may appear several times in a speech and these occurrences are used in order and before using the first occurrence of that word in the next speech.

输入描述

The input consists of several lines and provides a spoof to potentially create. The first input line contains an integer, mm (1≤m≤1001≤m≤100), representing the number of speeches for which there is text. Each of the speeches follows. Each speech is stored on a single line. The first token on each of these lines will be an integer, tt (1≤t≤10001≤t≤1000), representing the number of words in the speech.

Each of these words will consist of 1-20 lowercase letters. Words are separated by spaces and there are no other characters on these lines.

The input speeches are followed by a single line storing the lyrics of the song to be spoofed. The first token of this line will be an integer, ll (1≤l≤501≤l≤50), indicating the number of words in the lyrics. Each of these words will consist of 1-20 lowercase letters. The words in the lyrics are separated by spaces and there are no other characters on this line.

输出描述

If no spoof is possible, then simply output the string NOT POSSIBLE.

If a spoof is possible, output lines, where is the number of words in the song to spoof. Each line will contain two integers (separated by one space): the speech number and the word number, both of which are numbered, starting at 1.

样例输入:


8 tom brady threw a pass in the pocket
5 i sung very well today
8 the genie wishes i had one wish left
7 i threw a wish in the well

样例输出:

2 1
1 3
1 4
3 7
1 6
1 7
2 4

样例输入:


15 let it be told to the future world that we came forth to meet it
8 do not ask me i will never tell

样例输出:

NOT POSSIBLE

题目大意:

先输入几句话,最后一行输入一句话,将最后这句话中每个单词出现的位置进行输出,如果有多个位置,从第一个位置开始循环输出。如有有单词不存在则输出NOT POSSIBLE。

思路:

先设置一个map数组,嵌套一个vector数组,用来存单词出现的坐标,设另一个map数组用来记录最后这句话中单词出现的次数,来循环输出出现的坐标。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<string,vector<pair<int,int> > >mp;
map<string,int>mpcnt;
int main()
{
    int t;
    cin >> t;
    for(int i = 1;i <= t;i++){
        int n;
        cin >> n;
        for(int j = 1;j <= n;j++){
            string s;
            cin >> s;
            mp[s].push_back({i,j});
        }
    }
    int n;
    cin >> n;
    string s[110];
    for(int i = 1;i <= n;i++){
        cin >> s[i];
    }
    for(int i = 1;i <= n;i++){
        if(mp[s[i]].size() == 0)
        {
            cout << "NOT POSSIBLE";
            return 0;
        }
    }
    for(int i = 1;i <= n;i++){
        mpcnt[s[i]]++;
        cout << mp[s[i]][(mpcnt[s[i]]-1)%mp[s[i]].size()].first <<
            " " << mp[s[i]][(mpcnt[s[i]]-1)%mp[s[i]].size()].second << endl;
    }
}

H . Rummy Score

题目描述

Anya (Arup’s younger daughter) plays Rummy with a modified deck of playing cards. The card values are 1 through 13 (1 does not serve the dual purpose of 1 and 14; it is only 1) and there are no suits. Also, a deck may contain any number of each card value (unlike a standard deck of cards which has exactly four of each).

The Problem:

Given the seven cards in a Rummy hand (held by Anya), you are to determine the points lost by the hand. In Rummy, you group three (or more) cards together if they have the same value or they have consecutive values. Examples of a group include {4, 4, 4}, {6, 6, 6, 6, 6}, {9, 10, 11}, and {1, 2, 3, 4}. The “points lost by a hand” is the sum of values for cards that are not in a group.

When computing the points lost by a hand, you group the cards to minimize the loss, i.e., you want the smallest total sum of values for the ungrouped cards. Note that a given card could possibly belong to more than one group; you need to pick the group that minimizes the total points lost.

For example, given the seven cards {2, 2, 2, 3, 4, 8, 10}, the grouping {2, 3, 4} is better than the grouping {2, 2, 2}. Note also that a card can be used in only one group, e.g., from the Rummy hand {2, 2, 2, 3, 4, 8, 10}, we cannot create the two groups {2, 2, 2} and {2, 3, 4} since there are not a total of four cards with a value of 2 in the hand.

输入描述

The input consists of one line, containing seven integers, each integer between 1 and 13, inclusive (the values are separated by a single space).

输出描述

Print the points lost by the input hand.

样例输入1:

5 2 2 6 2 10 4

样例输出1:

10

样例输入2:

11 11 11 11 1 2 3

样例输出2:

0

样例输入3:

11 2 3 4 5 13 1

样例输出3:

24

题目大意:

给出7张1-13的纸牌,对其进行分组,3个及3个以上可以组成一组,连着的3个以上也可以组成一组,要求输出最后剩余没有分组的纸牌的综合最小。

思路:

这个题目因为数据很小,可以直接使用dfs搜索。当然还有其他的一些做法,使用选择判断进行。dfs代码相对比较好写一些。

dfs搜索的代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[15];
int ans = INT_MAX;
void dfs(int t)
{
    if(t > 13){
        int sum = 0;
        for(int i = 0;i <= 13;i++){
            sum += a[i]*i;
        }
        ans = min(ans,sum);
        return;
    }
    //顺子
    int cnt = 0;
    for(int i = t;i <= 13;i++){
        if(a[i] == 0)
            break;
        else
            cnt++;
        if(cnt >= 3){
            for(int j = t; j <= i;j++)
                a[j]--;
            dfs(t);
            for(int j = t; j <= i;j++)
                a[j]++;
        }
    }
    if(a[t] == 0)
        return dfs(t+1);
    //相同的
    if(a[t] >= 3){
        for(int i = 3;i <= a[t];i++){
            a[t] -= i;
            dfs(t);
            a[t] += i;
        }
    }

    dfs(t+1);
}
int main()
{
    for(int i = 0;i < 7;i++){
        int b;
        cin >> b;
        a[b]++;
    }
    dfs(1);
    cout << ans ;
}

选择判断的代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e2+10;

int a[10],sum,key,sum1,sum2;
map<int,int>mp;
map<int,int>mp1;
map<int,int>mp2;

int solve2()
{
	mp1=mp;mp2=mp;
	sum1=sum;sum2=sum;
	for(auto k : mp1)
	{
		if(k.second>=3)
		{
			sum1-=k.first*k.second;
			mp1[k.first]=0;
		}
	}
		
	for(auto k : mp1)
	{
		while(k.second>=1)
		{
			int s=k.first,ss=k.first;
			while(mp1[s+1]!=0) s++;
			
			if(s-k.first>=2)
			{
				for(int i=ss;i<=s;i++)
				{
					sum1-=i;
					mp1[i]--;
				}
			}
			else break;
		}
	}//先处理相同,在处理连续
	
	for(auto k : mp2)
	{
		while(k.second>=1)
		{
			int s=k.first,ss=k.first;
			while(mp2[s+1]!=0)	s++;
			
			if(s-k.first>=2)
			{
				for(int i=ss;i<=s;i++)
				{
					sum2-=i;
					mp2[i]--;
				}
			}
			else break;
		}
	}
	
	for(auto k : mp2)
	{
		if(k.second>=3)
		{
			sum2-=k.first*k.second;
			mp2[k.first]=0;
		}
	}//先处理连续,在处理相同
	
	
	return min(sum1,sum2);
}

int solve1()
{
	if(mp[key-1]&&mp[key-2]) return sum-key*6+3;
	else
	if(mp[key+1]&&mp[key+2]) return sum-key*6-3;
	else return solve2();
}

int main()
{
	for(int i=1;i<=7;i++) cin>>a[i],sum+=a[i],mp[a[i]]++;
	sort(a+1,a+1+7);
	
	bool flag=0;
	
	for(auto k : mp)
	{
		if(k.second==4) flag=1,key=k.first;
	}
	
	if(flag) cout<<solve1();
	else 	cout<<solve2();	
}

I . Simi Circles

题目描述

Arup has a step-daughter, Simi, at home, so he’s frequently in charge when she’s swimming with her friends. Unfortunately, after she’s done, Simi will run inside the house without completely drying herself. As she scurries through the house to the bathroom, she leaves drops of water that fall on the floor. Naturally, Arup’s wife, Anita, blames him for not properly watching the kids and making sure they properly dry themselves before entering the house. Anita will say that the wood was ruined by the water damage. But, of course, Arup realizes that not all of the wood is ruined. Thus, he only wants to take responsibility for the area of the wood floor that has water on it.

When Simi runs through the house, each drop of water hits the ground and forms a perfect circle. Furthermore, she runs fast enough that any drop at most intersects with the previous drop and no others. Sometimes a drop does not intersect with the previous drop. This means that any individual drop can at most intersect with two drops: the one before it and the one after it. Assume that each drop (circle) covers some area of the wood floor. In particular, assume that a circle will not be completely encompassed (covered) by another circle.

The Problem:

Given a list of circles, where a circle in the list may only intersect the previous circle on the list and the subsequent circle on the list, determine the total area that the circles cover.

输入描述

The first input line contains a single positive integer, nn (1≤n≤1001≤n≤100), indicating the number of Simi circle scenarios to consider. Each of the nn input sets follows. The first line of each input set contains only an integer, cc (1≤c≤1001≤c≤100), representing the number of drops for the input set. The following cc lines contain information about each drop, one drop per line, in the order that the drops occurred. Each of these lines contains exactly three real numbers (each separated from the next by a single space): xx (−3000<x<3000−3000<x<3000), yy (−3000<y<3000−3000<y<3000), and rr (0<r<100<r<10), representing (respectively) the xx and yy coordinates of the center of the drop (in cm) and the radius of the drop (in cm).

输出描述

For each Simi circle scenario, first output “Set #ii: ” where ii is the input set number, starting with 1. Follow this with a single positive real number rounded to 2 decimal places, representing the total area (in cm22) covered by all of the drops for the Simi circle scenario. Thus, if the actual area is 31.674 cm 2 , output 31.67 and if the actual area is 31.675 cm22 , output 31.68. Leave a blank line after the output for each test case. Follow the format illustrated in Sample Output.

样例输入:

3
2
0 0 1
0 2 1
2
0 0 5
6 0 5
1
0.1 0.1 0.1

样例输出:

Set #1: 6.28

Set #2: 134.71

Set #3: 0.03

题目大意:

圆形水滴与前或者后一个有重叠,但没有包含,给出圆形水滴的圆心坐标和半径,问这些水滴会覆盖多少面积?

思路:

这个题目的思路是非常的简单,就是把所有的圆的面积相加在减去重叠部分的面积,这个题目的主要点就在怎么求两个圆重叠部分的面积。所以我们先上一段求两个圆相交重叠部分的面积的代码。

两个圆相交求重叠部分的代码模板:

#define pi acos(-1.0)

struct node{
	double x;
	double y;
	double r;
}a[1001];
 
double area(node a,node b)
{
	double r1=a.r,r2=b.r;
	double d = sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
	if (d >= r1+r2)
		return 0;//相离
	if (r1>r2)
	{
		double tmp = r1;
		r1 = r2;
		r2 = tmp;
	}
	if(r2 - r1 >= d)
		return pi*r1*r1;//相交
	double ang1=acos((r1*r1+d*d-r2*r2)/(2*r1*d));
	double ang2=acos((r2*r2+d*d-r1*r1)/(2*r2*d));
	return ang1*r1*r1 + ang2*r2*r2 - r1*d*sin(ang1);
}

这个代码的具体证明过程附上一篇博客:两圆相交求相交部分的面积过程证明。 

接下来上这个题的代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pi acos(-1.0)

struct node{
	double x;
	double y;
	double r;
}a[1001];

double area(node a,node b)
{
	double r1=a.r,r2=b.r;
	double d = sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
	if (d >= r1+r2)
		return 0;//相离
	if (r1>r2)
	{
		double tmp = r1;
		r1 = r2;
		r2 = tmp;
	}
	if(r2 - r1 >= d)
		return pi*r1*r1;//相交
	double ang1=acos((r1*r1+d*d-r2*r2)/(2*r1*d));
	double ang2=acos((r2*r2+d*d-r1*r1)/(2*r2*d));
	return ang1*r1*r1 + ang2*r2*r2 - r1*d*sin(ang1);
}
int main()
{
    int t;
    cin >> t;
    for(int ii = 1;ii <= t;ii++){
        int n;
        cin >> n;
        for(int i = 0;i < n;i++){
            cin >> a[i].x >> a[i].y >> a[i].r;
        }
        double sum = 0;
        sum = pi*a[0].r*a[0].r;
        for(int i = 1;i < n;i++){
            sum += a[i].r*a[i].r*pi-area(a[i],a[i-1]);
        }
        printf("Set #%d: %.2lf\n\n",ii,sum);
    }
}

其余题目搞明白补完题后会持续更新......

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值