CodeForces Round 194 Div2

A. Candy Bags
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
Gerald has n younger brothers and their number happens to be even. One day he bought n2 candy bags. One bag has one candy, one bag has two candies, one bag has three candies and so on. In fact, for each integer k from 1 to n2 he has exactly one bag with k candies.

Help him give n bags of candies to each brother so that all brothers got the same number of candies.

Input
The single line contains a single integer n (n is even, 2≤n≤100) — the number of Gerald's brothers.

Output
Let's assume that Gerald indexes his brothers with numbers from 1 to n. You need to print n lines, on the i-th line print n integers — the numbers of candies in the bags for the i-th brother. Naturally, all these numbers should be distinct and be within limits from 1 to n2. You can print the numbers in the lines in any order.

It is guaranteed that the solution exists at the given limits.

Sample test(s)
Input
2
Output
1 4
2 3
题意:把1~N^2分成N组,使得每一组内的数字的和相同.
分析:先把N^2个数顺序分成N队,每队N个数,如 N=3,123|456|789.最终答案的每一组有N个数,每个数来自不同的队,而且每个数在其对应的队里的标号覆盖了[1,N]的区间.正确性显而易见,每队抽一个数且队标各不相同最终得到的和为0*N+d1+1*N+d2+2*N+d3+......(N-1)*N+dN=(0+1+......(N-1))*N+(1+2+......+N)=(N-1)*N^2/2+(N+1)*N/2=(N^3-N^2+N^2+N)/2=(N^3+N)/2.
不过最一开始WA了一次,原因在于我试图直接决定每一组的某一标号来自的队,会造成有的组无法抽数的情况.如N=3时
1 2 3
4 5 6
7 8 9
首先第一组取了1,5,9.第二组先取标号1得到4,再取标号2得到2.取标号3时只能从第三队取,而9已经被取过了,算法失败.

#include<stdio.h>
#include<string.h>
int N;
int g[125][125];
int main()
{
	int i,j,k;
	scanf("%d",&N);
	for (i=1;i<=N;i++) g[1][i]=i;
	for (i=2;i<=N;i++)
	{
		for (j=1;j<=N;j++)
		{
			if (j==1) g[i][j]=g[i-1][N];
			else g[i][j]=g[i-1][j-1];
		}
	}
	for (i=1;i<=N;i++)
	{
		int tmp=0;
		for (j=1;j<=N;j++)
		{
			printf("%d ",g[i][j]+tmp);
			tmp+=N;
		}
		printf("
");
	}
	return 0;
}

B. Eight Point Sets
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
Gerald is very particular to eight point sets. He thinks that any decent eight point set must consist of all pairwise intersections of three distinct integer vertical straight lines and three distinct integer horizontal straight lines, except for the average of these nine points. In other words, there must be three integers x1,x2,x3 and three more integers y1,y2,y3, such that x1<x2<x3, y1<y2<y3 and the eight point set consists of all points (xi,yj) (1≤i,j≤3), except for point (x2,y2).

You have a set of eight points. Find out if Gerald can use this set?

Input
The input consists of eight lines, the i-th line contains two space-separated integers xi and yi (0≤xi,yi≤106). You do not have any other conditions for these points.

Output
In a single line print word "respectable", if the given set of points corresponds to Gerald's decency rules, and "ugly" otherwise.

Sample test(s)
Input
0 0
0 1
0 2
1 0
1 2
2 0
2 1
2 2
Output
respectable
input
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
Output
ugly
 
Input
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
Output
ugly
题意:给出8个点,判断能否由三条横线和三条竖线除去中间的交点之外的8个点组成.
分析:直接判断即可,不过x,y要结合起来.

#include<stdio.h>
int x[10],y[10];
bool judge()
{
	int i,j;
	for (i=1;i<8;i++)
	 for (j=i+1;j<=8;j++)
	 if (x[i]>x[j] || (x[i]==x[j] && y[i]>y[j]))
	 {
		 int tmp=x[i];
		 x[i]=x[j];
		 x[j]=tmp;
		 tmp=y[i];
		 y[i]=y[j];
		 y[j]=tmp;
	 }
	if (x[1]!=x[2] || x[2]!=x[3]) return false;
	if (x[4]!=x[5]) return false;
	if (x[6]!=x[7] || x[7]!=x[8]) return false;
	if (x[3]==x[4]) return false;
	if (x[5]==x[6]) return false;
	if (y[1]!=y[4] || y[4]!=y[6]) return false;
	if (y[2]!=y[7]) return false;
	if (y[3]!=y[5] || y[5]!=y[8]) return false;
	if (y[1]==y[2] || y[2]==y[3]) return false;
	return true;
}
int main()
{
	int i;
	for (i=1;i<=8;i++) scanf("%d%d",&x[i],&y[i]);
	if (judge()) printf("respectable
");
	else printf("ugly
");
}

C. Secrets
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
Gerald has been selling state secrets at leisure. All the secrets cost the same: n marks. The state which secrets Gerald is selling, has no paper money, only coins. But there are coins of all positive integer denominations that are powers of three: 1 mark, 3 marks, 9 marks, 27 marks and so on. There are no coins of other denominations. Of course, Gerald likes it when he gets money without the change. And all buyers respect him and try to give the desired sum without change, if possible. But this does not always happen.

One day an unlucky buyer came. He did not have the desired sum without change. Then he took out all his coins and tried to give Gerald a larger than necessary sum with as few coins as possible. What is the maximum number of coins he could get?

The formal explanation of the previous paragraph: we consider all the possible combinations of coins for which the buyer can not give Gerald the sum of n marks without change. For each such combination calculate the minimum number of coins that can bring the buyer at least n marks. Among all combinations choose the maximum of the minimum number of coins. This is the number we want.

Input
The single line contains a single integer n (1≤n≤1017).

Please, do not use the %lld specifier to read or write 64 bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.

Output
In a single line print an integer: the maximum number of coins the unlucky buyer could have paid with.

Sample test(s)
Input
1
Output
1
Input
4
Output
2
Note
In the first test case, if a buyer has exactly one coin of at least 3 marks, then, to give Gerald one mark, he will have to give this coin. In this sample, the customer can not have a coin of one mark, as in this case, he will be able to give the money to Gerald without any change.

In the second test case, if the buyer had exactly three coins of 3 marks, then, to give Gerald 4 marks, he will have to give two of these coins. The buyer cannot give three coins as he wants to minimize the number of coins that he gives.

题意:所有的硬币面额都是3的幂,给出价格N,假设N无法由目前所有的硬币组合成,那么求在多花最少钱的情况下最多用多少枚硬币.

分析:找到最小的K使得N不是3^K的倍数,答案即为N/3^K+1

 

#include<stdio.h>
__int64 N,g[40];
int main()
{
	int x,i;
	g[0]=1;
	for (i=1;i<40;i++) g[i]=g[i-1]*3;
	scanf("%I64d",&N);
	for (i=0;i<40;i++)
		if (N%g[i]!=0)
		{
			x=i;
			break;
		}
	printf("%I64d
",N/g[x]+1);
	return 0;
}

 

D. Chips
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
Gerald plays the following game. He has a checkered field of size n×n cells, where m various cells are banned. Before the game, he has to put a few chips on some border (but not corner) board cells. Then for n-1 minutes, Gerald every minute moves each chip into an adjacent cell. He moves each chip from its original edge to the opposite edge. Gerald loses in this game in each of the three cases:

At least one of the chips at least once fell to the banned cell.
At least once two chips were on the same cell.
At least once two chips swapped in a minute (for example, if you stand two chips on two opposite border cells of a row with even length, this situation happens in the middle of the row).
 

In that case he loses and earns 0 points. When nothing like that happened, he wins and earns the number of points equal to the number of chips he managed to put on the board. Help Gerald earn the most points.

Input
The first line contains two space-separated integers n and m (2≤n≤1000, 0≤m≤105) — the size of the field and the number of banned cells. Next m lines each contain two space-separated integers. Specifically, the i-th of these lines contains numbers xi and yi (1≤xi,yi≤n) — the coordinates of the i-th banned cell. All given cells are distinct.

Consider the field rows numbered from top to bottom from 1 to n, and the columns — from left to right from 1 to n.

Output
Print a single integer — the maximum points Gerald can earn in this game.

Sample test(s)
Input
3 1
2 2
Output
0
Input
3 0
Output
1
Input
4 3
3 1
3 2
3 3
Output
1

题意:在N*N的棋盘边上放置棋子,每分钟把棋子向对面移动一格,要求不能进入某些特定位置,两枚棋子在某一分钟不能位于同一格且不能交换位置.求最多放多少个棋子.
分析:一个不能进入的位置能废掉一行和一列.设x[i]表示第i行能不能放,y[i]表示列.对于某个i来说,如果x[i]或y[i]中有真那么这里至少能放一个.如果x与y的值同时为真,则有希望放两个(行列各一个).此时需满足这两枚棋子不能同时出现在交叉点.显然只有当n为奇数且该交点位于棋盘正中央时这是不可避免的.

 

#include<stdio.h>
#include<string.h>
int N,M,i;
bool x[1025],y[1025];
int main()
{
	//while (1)
	{
	memset(x,true,sizeof(x));
	memset(y,true,sizeof(y));
	scanf("%d%d",&N,&M);
	for (i=1;i<=M;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		x[a]=false;
		y[b]=false;
	}
	int ans=0;
	for (i=2;i<N;i++)
	{
		if (x[i] || y[i]) ans++;
		if (x[i] && y[i] && (N%2==0 || (N+1)/2!=i)) ans++;
	}
	printf("%d
",ans);
	}
	return 0;
}

 

 E. Lucky Tickets
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Gerald has a friend, Pollard. Pollard is interested in lucky tickets (ticket is a sequence of digits). At first he thought that a ticket is lucky if between some its digits we can add arithmetic signs and brackets so that the result obtained by the arithmetic expression was number 100. But he quickly analyzed all such tickets and moved on to a more general question. Now he explores k-lucky tickets.

Pollard sais that a ticket is k-lucky if we can add arithmetic operation signs between its digits to the left or right of them (i.e., "+", "-", "×") and brackets so as to obtain the correct arithmetic expression whose value would equal k. For example, ticket "224201016" is 1000-lucky as (-2-(2+4))×(2+0)+1016=1000.

Pollard was so carried away by the lucky tickets that he signed up for a seminar on lucky tickets and, as far as Gerald knows, Pollard will attend it daily at 7 pm in some famous institute and will commute to it in the same tram for m days. In this tram tickets have eight digits. And Gerald wants to make a surprise for Pollard: each day Pollard will receive a tram k-lucky ticket. The conductor has already agreed to give Pollard certain tickets during all these m days and he only wants Gerald to tell him what kind of tickets to give out. In this regard, help Gerald pick exactly m distinct k-lucky tickets.

Input
The single line contains two integers k and m (0≤k≤104, 1≤m≤3·105).

Output
Print m lines. Each line must contain exactly 8 digits — the k-winning ticket. The tickets may begin with 0, all tickets must be distinct. If there are more than m distinct k-lucky tickets, print any m of them. It is guaranteed that at least m distinct k-lucky tickets exist. The tickets can be printed in any order.

Sample test(s)
Input
0 3
Output
00000000
00000001
00000002
 
Input
7 4
Output
00000007
00000016
00000017
00000018
题意:对于输入K和M构造8个数码,使得通过加入运算符和括号之后运算结果为K,这样的8个数码构造M组.
被虐了,膜拜大神的代码

 

#pragma comment(linker, "/STACK:256000000")
#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cassert>
#include <sstream>

using namespace std;

#define forn(i, n) for (int i = 0; i < int(n); i++)
#define for1(i, n) for (int i = 1; i <= int(n); i++)
#define forv(i, v) forn(i, v.size())

#define all(x) x.begin(), x.end()
#define pb push_back
#define mp make_pair

#define CIN_FILE "input.txt"
#define COUT_FILE "output.txt"

typedef long double ld;
typedef long long ll;
typedef pair<int, int> pii;

set<int> s;

int seq[10];
int cnt = 0;
int m;

void outdata()
{
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
    {
        printf("%08d
", *it);
    }
    exit(0);
}

void construct()
{
    int p[8];


    forn(mask, (1 << 8))
    {
        int l = 0, r = 7;
        forn(i, 7)
        {
            if (mask & (1 << i)) p[l++] = seq[i]; else p[r--] = seq[i];
        }
        p[l++] = seq[7];

        int num = 0;
        forn(i, 8)
        {
            num = num * 10 + p[i];
        }
        s.insert(num);

        if ((int)s.size() == m)
        {
            outdata();
        }
    }
}

void gen(int k)
{
    if (cnt > 7) return;
 
    if (cnt == 7)
    {
        if (k > 9) return;

        seq[cnt++] = k;
        construct();
        cnt--;
        return;
    }

    vector<int> p;
    for (int i = 2; i <= 9; i++) p.pb(i);
    random_shuffle(all(p));

    forv(i1, p)
    {
        int i = p[i1];
        if (k % i == 0)
        {
            seq[cnt++] = i;
            gen(k / i);
            cnt--;
        }

        if (cnt > 5) continue;

        forn(j, 10)
        {
            if (k > j && (k -j) % i == 0) 
            {
                seq[cnt++] = j;
                seq[cnt++] = i;

                gen((k -j) / i);
                cnt--;
                cnt--;
            }
            if ((k + j) % i == 0) 
            {
                seq[cnt++] = j;
                seq[cnt++] = i;

                gen((k + j) / i);
                cnt--;
                cnt--;
            }
        }
    }


}
int main()
{

    int k;

    cin >> k >> m;

    gen(k);

    return 0;
}

 

 

 

原文地址:https://www.cnblogs.com/dramstadt/p/3220971.html