qdu_ACM3月7号组队训练

A Second-price Auction

Do you know second-price auction? It’s very simple but famous. In a second-price auction, each potential buyer privately submits, perhaps in a sealed envelope or over a secure connection, his (or her) bid for the object to the auctioneer. After receiving all the bids, the auctioneer then awards the object to the bidder with the highest bid, and charges him (or her) the amount of the second-highest bid.

Suppose you’re the auctioneer and you have received all the bids, you should decide the winner and the amount of money he (or she) should pay.

Input
There are multiple test cases. The first line of input contains an integer T(T <= 100), indicating the number of test cases. Then T test cases follow.

Each test case contains two lines: The first line of each test case contains only one integer N, indicating the number of bidders. (2 <= N <= 100) The second line of each test case contains N integers separated by a space. The i-th integer Pi indicates the i-th bidder’s bid. (0 < Pi <= 60000) You may assume that the highest bid is unique.

Output
For each test case, output a line containing two integers x and y separated by a space. It indicates that the x-th bidder is the winner and the amount of money he (or she) should pay is y.

Sample Input
2
3
3 2 1
2
4 9

Sample Output
1 2
2 4
说实话,没看清楚题,但是觉得题很简单,看样例就会了。代码如下:

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

const int maxx=1e4+100;
struct node{
	int val;
	int pos;
}p[maxx];

bool cmp(const node &a,const node &b)
{
	return a.val>b.val;
}

int n;

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;i++) scanf("%d",&p[i].val),p[i].pos=i;
		sort(p+1,p+1+n,cmp);
		printf("%d %d\n",p[1].pos,p[2].val);
	}
}

Connect them
You have n computers numbered from 1 to n and you want to connect them to make a small local area network (LAN). All connections are two-way (that is connecting computers i and j is the same as connecting computers j and i). The cost of connecting computer i and computer j is cij. You cannot connect some pairs of computers due to some particular reasons. You want to connect them so that every computer connects to any other one directly or indirectly and you also want to pay as little as possible.

Given n and each cij , find the cheapest way to connect computers.

Input
There are multiple test cases. The first line of input contains an integer T (T <= 100), indicating the number of test cases. Then T test cases follow.

The first line of each test case contains an integer n (1 < n <= 100). Then n lines follow, each of which contains n integers separated by a space. The j-th integer of the i-th line in these n lines is cij, indicating the cost of connecting computers i and j (cij = 0 means that you cannot connect them). 0 <= cij <= 60000, cij = cji, cii = 0, 1 <= i, j <= n.

Output
For each test case, if you can connect the computers together, output the method in in the following fomat:

i1 j1 i1 j1 …

where ik ik (k >= 1) are the identification numbers of the two computers to be connected. All the integers must be separated by a space and there must be no extra space at the end of the line. If there are multiple solutions, output the lexicographically smallest one (see hints for the definition of “lexicography small”) If you cannot connect them, just output “-1” in the line.

Sample Input
2
3
0 2 3
2 0 5
3 5 0
2
0 0
0 0

Sample Output
1 2 1 3
-1

Hint
s:
A solution A is a line of p integers: a1, a2, …ap.
Another solution B different from A is a line of q integers: b1, b2, …bq.
A is lexicographically smaller than B if and only if:
(1) there exists a positive integer r (r <= p, r <= q) such that ai = bi for all 0 < i < r and ar < br
OR
(2) p < q and ai = bi for all 0 < i <= p

最小生成树+字典序最小输出。
在存储边的时候,就按着字典序最小存储,排序的时候,也是按着字典序最小排列。在对边输出时,也是按着字典序有小到大排列。最好是在并查集完了之后在判断是不是个树,要不容易出错
代码如下:

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

int a[101][101];
int n;
int f[10100];
struct node{
	int u;
	int v;
	int val;
}p[10101];

struct node2{
	int x;
	int y;
}p2[10101];

bool cmp1(const node &a,const node &b)
{
	if(a.val!=b.val)
	return a.val<b.val;
	else if(a.u!=b.u) return a.u<b.u;
	else return a.v<b.v;
}

bool cmp2(const node2 &a,const node2 &b)
{
	if(a.x!=b.x) return a.x<b.x;
	else return a.y<b.y;
}

int getf(int u)
{
	if(u!=f[u]) return f[u]=getf(f[u]);
	else return u;
}

int merge(int u,int v)
{
	int t1=getf(u);
	int t2=getf(v);
	if(t1!=t2)
	{
		f[t2]=t1;
		return 1;
	}
	return 0;
}

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		memset(f,0,sizeof(f));
		memset(p,0,sizeof(p));
		memset(p2,0,sizeof(p2));
		memset(a,0,sizeof(a));
		scanf("%d",&n);
		int flag=0;
		for(int i=1;i<=n;i++)
		{
			f[i]=i;
			for(int j=1;j<=n;j++)
			{
				scanf("%d",&a[i][j]);
				if(a[i][j]) flag++;
			}
		}
		int cnt=0;
		for(int i=1;i<=n;i++)
		{
			for(int j=i;j<=n;j++)
			{
				if(a[i][j]!=0)
				{
					p[cnt].u=i;p[cnt].v=j;p[cnt++].val=a[i][j];
				}
				
			}
		}
		sort(p,p+cnt,cmp1);
		int ant=0;
		int cnt1=0;
		for(int i=0;i<cnt;i++)
		{
			int u=p[i].u;
			int v=p[i].v;
			if(merge(u,v))
			{
				ant++;
				p2[cnt1].x=min(u,v);
				p2[cnt1++].y=max(u,v);
			}
			if(ant==n-1) break;
		}
		if(ant<n-1){
			printf("-1\n");
			continue;
		}
		sort(p2,p2+cnt1,cmp2);
		for(int i=0;i<cnt1;i++)
		{
			printf("%d %d",p2[i].x,p2[i].y);
			if(i<cnt1-1) printf(" ");
		}
		printf("\n");
	}
}

80ers’ Memory
I guess most of us are so called 80ers, which means that we were born in the 1980’s. This group of people shared a lot of common memories. For example, the Saint Seiya, the YoYo ball, the Super Mario, and so on. Do you still remember these?

Input
There will be ONLY ONE test case.

The test case begins with a positive integer N, (N < 100).
Then there will be N lines each containing a single word describing a keyword of the typical 80ers’ memories. Each word consists of letters, [a-zA-Z], numbers, [0-9], and the underline, ‘_’. The length of each word would be no more than 20.
Then one line follows with a positive integer K, (K < 100).
The last part of the test case will be K lines. The i-th line contains the keywords given by the i-th person and starts with a positive integer Ni. Then there will be Ni words separated by white spaces. Each of these words has no more than 20 characters.
All the words are case sensitive.

Output
For each of these K people, you are asked to count the number of typical 80ers’ keywords on his/her list and output it in a single line.

Sample Input
4
Saint_Seiya
YoYo_ball
Super_Mario
HuLuWa
3
2 Saint_Seiya TiaoFangZi
1 KTV
3 HuLuWa YOYO_BALL YoYo_ball

Sample Output
1
0
2

水题第二发
代码如下:

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

map<string,int> mp;

int n;

int main()
{
	scanf("%d",&n);
	string a,s;
	for(int i=0;i<n;i++)
	{
		cin>>a;
		mp[a]=1;
	}
	int m;
	scanf("%d",&m);
	while(m--)
	{
		int x;
		scanf("%d",&x);
		int sum=0;
		while(x--)
		{
			cin>>s;
			if(mp[s]) sum++;
		}
		printf("%d\n",sum);
	}
}

A Stack or A Queue? 水题第三发
Do you know stack and queue? They’re both important data structures. A stack is a “first in last out” (FILO) data structure and a queue is a “first in first out” (FIFO) one.

Here comes the problem: given the order of some integers (it is assumed that the stack and queue are both for integers) going into the structure and coming out of it, please guess what kind of data structure it could be - stack or queue?

Notice that here we assume that none of the integers are popped out before all the integers are pushed into the structure.

Input
There are multiple test cases. The first line of input contains an integer T (T <= 100), indicating the number of test cases. Then T test cases follow.

Each test case contains 3 lines: The first line of each test case contains only one integer N indicating the number of integers (1 <= N <= 100). The second line of each test case contains N integers separated by a space, which are given in the order of going into the structure (that is, the first one is the earliest going in). The third line of each test case also contains N integers separated by a space, whick are given in the order of coming out of the structure (the first one is the earliest coming out).

Output
For each test case, output your guess in a single line. If the structure can only be a stack, output “stack”; or if the structure can only be a queue, output “queue”; otherwise if the structure can be either a stack or a queue, output “both”, or else otherwise output “neither”.

Sample Input
4
3
1 2 3
3 2 1
3
1 2 3
1 2 3
3
1 2 1
1 2 1
3
1 2 3
2 3 1

Sample Output
stack
queue
both
neither
判断是栈还是队列。千万别把单词写错了。
代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
	int z;
	cin>>z;
	int l[120]={0};
	for(int w=0;w<z;w++)
	{
		int n;
		cin>>n;
		int a[120],b[120];
		int i;
		for(i=0;i<n;i++)
			cin>>a[i];
		for(i=0;i<n;i++)
			cin>>b[i];
		int j=0,k=0;
		for(i=0;i<n;i++)
		{
			if(a[i]==b[i])
				j++;
		}
		for(i=0;i<n;i++)
		{
			if(a[i]==b[n-1-i])
				k++;
		}
		if(j==n)
			l[w]=5;
		if(k==n)
			l[w]=10;
		if(j==n && k==n)
			l[w]=20;
	}
	for(int w=0;w<z;w++)
	{
		if(l[w]==0)
			cout<<"neither"<<endl;
		if(l[w]==5)
			cout<<"queue"<<endl;
		if(l[w]==10)
			cout<<"stack"<<endl;
		if(l[w]==20)
			cout<<"both"<<endl;
	}
}

K-Nice
This is a super simple problem. The description is simple, the solution is simple. If you believe so, just read it on. Or if you don’t, just pretend that you can’t see this one.

We say an element is inside a matrix if it has four neighboring elements in the matrix (Those at the corner have two and on the edge have three). An element inside a matrix is called “nice” when its value equals the sum of its four neighbors. A matrix is called “k-nice” if and only if k of the elements inside the matrix are “nice”.

Now given the size of the matrix and the value of k, you are to output any one of the “k-nice” matrix of the given size. It is guaranteed that there is always a solution to every test case.

Input
The first line of the input contains an integer T (1 <= T <= 8500) followed by T test cases. Each case contains three integers n, m, k (2 <= n, m <= 15, 0 <= k <= (n - 2) * (m - 2)) indicating the matrix size n * m and it the “nice”-degree k.

Output
For each test case, output a matrix with n lines each containing m elements separated by a space (no extra space at the end of the line). The absolute value of the elements in the matrix should not be greater than 10000.

Sample Input
2
4 5 3
5 5 3

Sample Output
2 1 3 1 1
4 8 2 6 1
1 1 9 2 9
2 2 4 4 3
0 1 2 3 0
0 4 5 6 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
就是找k个数,他们等于周围四个数的和。没有空格!!!!因为这个wa了两次
代码如下:

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

const int maxx=101;
int a[maxx][maxx];
int n,m,k;

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d%d",&n,&m,&k);
		for(int i=0;i<n;i++)
		for(int j=0;j<m;j++) a[i][j]=1;
		for(int i=1;i<n-1;i++)
		{
			for(int j=1;j<m-1;j++)
			{
				if(k==0) break;
				a[i][j]=0;
				a[i-1][j]=0;a[i+1][j]=0;a[i][j-1]=0;a[i][j+1]=0;
				k--;
			}
			if(k==0) break;
		}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				printf("%d",a[i][j]);
				if(j<m-1) printf(" "); 
			} 
			printf("\n");
		}
	}
}

Dream City
JAVAMAN is visiting Dream City and he sees a yard of gold coin trees. There are n trees in the yard. Let’s call them tree 1, tree 2 …and tree n. At the first day, each tree i has ai coins on it (i=1, 2, 3…n). Surprisingly, each tree i can grow bi new coins each day if it is not cut down. From the first day, JAVAMAN can choose to cut down one tree each day to get all the coins on it. Since he can stay in the Dream City for at most m days, he can cut down at most m trees in all and if he decides not to cut one day, he cannot cut any trees later. (In other words, he can only cut down trees for consecutive m or less days from the first day!)

Given n, m, ai and bi (i=1, 2, 3…n), calculate the maximum number of gold coins JAVAMAN can get.

Input
There are multiple test cases. The first line of input contains an integer T (T <= 200) indicates the number of test cases. Then T test cases follow.

Each test case contains 3 lines: The first line of each test case contains 2 positive integers n and m (0 < m <= n <= 250) separated by a space. The second line of each test case contains n positive integers separated by a space, indicating ai. (0 < ai <= 100, i=1, 2, 3…n) The third line of each test case also contains n positive integers separated by a space, indicating bi. (0 < bi <= 100, i=1, 2, 3…n)

Output
For each test case, output the result in a single line.

Sample Input
2
2 1
10 10
1 1
2 2
8 10
2 3

Sample Output
10
21

Hint
s:
Test case 1: JAVAMAN just cut tree 1 to get 10 gold coins at the first day.
Test case 2: JAVAMAN cut tree 1 at the first day and tree 2 at the second day to get 8 + 10 + 3 = 21 gold coins in all.
又是一个贪心+dp,按着增长速度由小到大排序,这样的话就会发挥它的最大价值。
dp[i][j]代表着前i颗树砍了j颗数的最大值
代码如下:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#include<queue>
#define eps 1e-5
#define N 501
#define pi acos(-1)
#define mod 10007
using namespace std;
typedef long long ll;
struct node
{
	int n,r;
}a[300];
bool cmp(node a,node b)
{
	return a.r<b.r;
}
int dp[300][300];//dp[i][j]代表前i颗数在第j天砍的最大价值 
int main ()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int n,k;
		scanf("%d %d",&n,&k);
		for(int i=1;i<=n;i++)
			scanf("%d",&a[i].n);
		for(int i=1;i<=n;i++)
			scanf("%d",&a[i].r);
		memset(dp,0,sizeof(dp));
		sort(a+1,a+1+n,cmp);
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=k;j++)
			{
				dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+a[i].n+(j-1)*a[i].r);
			}
		}
		printf("%d\n",dp[n][k]);
	}
	return 0;
}

努力加油a啊,(o)/~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

starlet_kiss

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

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

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

打赏作者

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

抵扣说明:

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

余额充值