Gym 101078

A题

比较两个由数字1~n组成的序列,输出每段最短的相似的序列。(相似代表这段中两个序列包含的数字相同,顺序可以不同)

Input
2
10
1 2 3 6 4 7 5 8 9 10
3 2 1 4 5 6 7 8 10 9
5
2 1 4 5 3
2 4 5 3 1
Output
1-3 4-7 8-8 9-10
1-1 2-5


用一个hash数组来标记某数字出现的次数,每扫描到一个数字就把它的出现次数加一。如果扫描到的数字出现次数为0,就把数字总数加1;如果为1,就把数字总数减1. 若总数为0,说明所有数字都出现了2次,输出当前区间即可。

用变量s记录区间的位置。

#include
#include
using namespace std;

int a[100010],b[100010],num[100010];
int main()
{
	int _,n,sum;

	scanf("%d",&_);
	while (_--){
		scanf("%d",&n);
		for (int i=0; i

也可以用优先队列记录俩个序列里的值,每加入一个就把它们中的相同元素去掉,直到两个优先队列都为空为止。

Gym 101078_第1张图片

D题

Collatz
Problem
In the process to solve the Collatz conjecture, better known as the 3n + 1 problem, Carl created a
physical model with wood and ropes. A wooden bar contains a hole for every natural number from
1 to infinity from left to right. For every even number m there is a rope connecting the mth hole
with hole m/2 . For every odd number n there is a rope connecting the nth hole with hole 3n + 1.
For an important conference where Carl plans to elaborate on his results, he wants to bring
his structure, but it is too large to fit in his bag. So he decided to saw o the part of the bar
containing the first N holes only. How many ropes will he need to cut?
Input
The first line of the input contains a single number: the number of test cases to follow. Each test
case has the following format:
• One line with an integer N, satisfying 0 ≤ N ≤
109 .
Output
For every test case in the input, the output should contain a single number, on a single line: the
number of ropes that need to be cut.
Example
Input
3
12
240
3600
Output
10
200
3000

手算出来奇数情况和偶数情况下需要割断的绳子数即可。

#include
#include
using namespace std;

int main()
{
	int _,n,ans;

	scanf("%d",&_);
	while (_--){
		scanf("%d",&n);
		ans=0;
		if (n&1)
		{
			ans+=n-n/2;
			ans+=(n-(n-1)/3+1)/2;
		}
		else{
			ans+=n/2;
			ans+=(n-(n-1)/3)/2;
		}
		printf("%d\n",ans);
	}



	return 0;
}

I题

I Keylogger
Problem
As a malicious hacker you are trying to steal your mother’s password, and therefore you have
installed a keylogger on her PC (or Mac, so you like). You have a log from your mother typing
the password, but unfortunately the password is not directly visible because she used the left and
right arrows to change the position of the cursor, and the backspace to delete some characters.
Write a program that can decode the password from the given keylog.
Input
The first line of the input contains a single number: the number of test cases to follow. Each test
case has the following format:
• One line with a string L, satisfying 1 ≤ Length(L) ≤ 1, 000, 000, consisting of:
– ’-’ representing backspace: the character directly before the cursor position is deleted,
if there is any.
– ’<’(and ’>’) representing the left (right) arrow: the cursor is moved 1 character to
the left (right), if possible.
– alphanumeric characters, which are part of the password, unless deleted later. We
assume ‘insert mode’: if the cursor is not at the end of the line, and you type an
alphanumeric character, then all characters after the cursor move one position to the
right.
Every decoded password will be of length > 0.
Output
For every test case in the input, the output should contain a single string, on a single line: the
decoded password.
Example
Input
2
<>Cd-
ThIsIsS3Cr3t
Output
BAPC
ThIsIsS3Cr3t
This page intentionally left blank.

链表模拟题

Gym 101078_第2张图片

J题

题目大意:

    有t组输入 ,接下来两行,表示横着的字符串有多少个,竖着的字符串有多少个,然后接下来那些行每行三个元素,表示起点坐标,和字符串。问最多能够在方格纸上写下多少字符串,并且使其都没有矛盾。

    题目保证只有横竖的字符串会有交点。

思路:

    横着和竖着的单词看成两类点,冲突看成边,求出最大独立集就可以得到两两间没有冲突的单词数。

    最大独立集=顶点个数 – 最小顶点覆盖(最大匹配)

 

#include 
#include 
#include 
using namespace std;
int e[1051][1001];
int match[1110];
int book[1100];
int n,m;
int dfs(int u)
{
    for(int i=1;i<=m;i++)
    {
        if(book[i]==0&&e[u][i]==1)
        {
            book[i]=1; //标记点i已访问过
            if(match[i]==0||dfs(match[i]))
            {
                //更新配对关系
                match[i]=u;
                return 1;//把dfs(u)置为true
            }
        }
    }
    return 0;
}

int xh[550],yh[550],xv[550],yv[550];
   char h[550][1010],v[550][1010];
int main()
{
   int _;
   scanf("%d",&_);
   while (_--){
 	
   scanf("%d%d",&n,&m);
 	
   for(int i=1;i<=n;i++){
    	scanf("%d%d",&xh[i],&yh[i]);
    	scanf("%s",h[i]);
   }
   for(int i=1;i<=m;i++){
    	scanf("%d%d",&xv[i],&yv[i]);
    	scanf("%s",v[i]);
   }
   for (int i=1; i<=n+m; i++)
   	for (int j=1; j<=n+m; j++)
   		e[i][j]=0;
// int pp=0;

//建边
   for (int i=1; i<=n; i++){
	   	for (int j=1; j<=m; j++){
	   		if ((yh[i]=yv[j]+(int)strlen(v[j]))) continue;
	   		if ((xv[j]=xh[i]+(int)strlen(h[i]))) continue;
	   		if (h[i][xv[j]-xh[i]]!=v[j][yh[i]-yv[j]]){
		   		e[i][j]=1;
		   		// printf("i,j:%d %d\n",i,j );
		   		// pp++;
		   	}
		}
   	}
	// printf("ppp: %d\n",pp );
	// n+=m;
	for(int i=1;i<=m;i++)
    	match[i]=0;
 	
 	int sum=0;

	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++)
        	book[j]=0;           //清空上次搜索时的标记
    	if(dfs(i))
        	sum++;           
        	   //寻找增广路,如果找到,配对数加1.
   	}

	printf("%d\n",n+m-sum);}
    return 0;
}
/*
2
2 2
0 1 BAPC
0 2 LEIDEN
0 0 SOLUTION
2 1 WINNER
1 4
0 1 HELLO
1 0 HI
2 0 BYE
3 0 GOODBYE
4 0 FAREWELL
*/

 

你可能感兴趣的:(队切训练)