Educational Codeforces Round 20

1.题目链接

http://codeforces.com/contest/803/problem/A

2.题面

A. Maximal Binary Matrix
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given matrix with n rows and n columns filled with zeroes. You should put k ones in it in such a way that the resulting matrix is symmetrical with respect to the main diagonal (the diagonal that goes from the top left to the bottom right corner) and is lexicographically maximal.

One matrix is lexicographically greater than the other if the first different number in the first different row from the top in the first matrix is greater than the corresponding number in the second one.

If there exists no such matrix then output -1.

Input

The first line consists of two numbers n and k (1 ≤ n ≤ 1000 ≤ k ≤ 106).

Output

If the answer exists then output resulting matrix. Otherwise output -1.

Examples
input
Copy
2 1
output
Copy
1 0 
0 0 
input
Copy
3 2
output
Copy
1 0 0 
0 1 0 
0 0 0 
input
Copy
2 5
output
Copy
-1

3.题意

就是给你一个n*n的矩阵,让你填充其中的k个点,使这个矩阵满足关于对角线对称并且字典序最大。1<=n<=100,0<=k<=1e6.

4.思路

水题,可以想到字典序最大,就是按照先行后列的原则,所以直接采取双重for循环,如果当前点在对角线上,直接填充,如果不在,判断当前k是否大于2,每次填充之后更新k,当k==0退出循环。

5.代码实现

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<vector>
#include <time.h>
#include<string.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <db, db> pdd;

const int maxn = 105;
const int Mod=1000000007;
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const double e=2.718281828459045235360287471352662;
const db PI = acos(-1);
const db ERR = 1e-10;

#define Se second
#define Fi first
#define pb push_back
int a[maxn][maxn];
int main()
{
    ios::sync_with_stdio(false);
    int n,k;
    cin>>n>>k;
    if(k>n*n)
    {
        cout<<-1<<endl;
        return 0;
    }
    for(int i=0;i<n;i++)
    {
        if(k==0)
            break;
        for(int j=0;j<n;j++)
        {
            if(k==0)
                break;
            if(a[i][j]==0)
            {
                if(i==j)
                {
                    a[i][j]=1;
                    k--;
                }
                else
                {
                    if(k>=2)
                    {
                        a[i][j]=1;
                        a[j][i]=1;
                        k-=2;
                    }
                }
            }
            if(k==0)
                break;
        }
        if(k==0)
            break;
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
    }
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}

6.反思

对于k最初等于0的条件没有考虑。以后每个if判断是否满足条件,不要在之后判断。


1.题目链接

http://codeforces.com/contest/803/problem/B

2.题面

B. Distances to Zero
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given the array of integer numbers a0, a1, ..., an - 1. For each element find the distance to the nearest zero (to the element which equals to zero). There is at least one zero element in the given array.

Input

The first line contains integer n (1 ≤ n ≤ 2·105) — length of the array a. The second line contains integer elements of the array separated by single spaces ( - 109 ≤ ai ≤ 109).

Output

Print the sequence d0, d1, ..., dn - 1, where di is the difference of indices between i and nearest j such that aj = 0. It is possible that i = j.

Examples
input
Copy
9
2 1 0 3 0 0 3 2 4
output
Copy
2 1 0 1 0 0 1 2 3 
input
Copy
5
0 1 2 3 4
output
Copy
0 1 2 3 4 
input
Copy
7
5 6 0 1 -2 3 4
output
Copy
2 1 0 1 2 3 4 

3.题意

给以一个数组,要你求每个数到最近的0的距离。

4.思路

我的思路是nlogn的,将所有0的地址存进另一个数组,然后对于每个位置二分查找离他最近的下一个0的位置,然后对于当前位置的0和上一个位置的0进行取min。

还有一个o(n)的思路,就是直接从前往后遍历数组,用pre数组来保存每个元素上一个0的位置。然后从后往前遍历数组,用next数组保存下一个0的位置,最后遍历一遍,两者取min。

5.代码实现

本代码为nlogn实现

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<vector>
#include <time.h>
#include<string.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <db, db> pdd;

const int maxn = 2e5+5;
const int Mod=1000000007;
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const double e=2.718281828459045235360287471352662;
const db PI = acos(-1);
const db ERR = 1e-10;

#define Se second
#define Fi first
#define pb push_back
int a[maxn];
int b[maxn];
int n;
int main()
{
    ios::sync_with_stdio(false);
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    cin>>n;
    int cnt=0;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
        if(a[i]==0)
            b[cnt++]=i;
    }
    for(int i=0;i<n;i++)
    {
        int pos=lower_bound(b,b+cnt,i)-b;
        if(pos==0)
            cout<<b[0]-i<<" ";
        else if(pos==cnt)
            cout<<i-b[pos-1]<<" ";
        else
            cout<<min(b[pos]-i,i-b[pos-1])<<" ";
    }
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}

6.反思

水题,注意细节和手速就好

1.题目链接

http://codeforces.com/contest/803/problem/C

2.题面

C. Maximal GCD
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given positive integer number n. You should create such strictly increasing sequence of k positive numbers a1, a2, ..., ak, that their sum is equal to n and greatest common divisor is maximal.

Greatest common divisor of sequence is maximum of such numbers that every element of sequence is divisible by them.

If there is no possible sequence then output -1.

Input

The first line consists of two numbers n and k (1 ≤ n, k ≤ 1010).

Output

If the answer exists then output k numbers — resulting sequence. Otherwise output -1. If there are multiple answers, print any of them.

Examples
input
Copy
6 3
output
Copy
1 2 3
input
Copy
8 2
output
Copy
2 6
input
Copy
5 3
output
Copy
-1

3.题意

就是给你一个n,让你分解成k个数之和,并保证这k个数的GCD最大。

4.思路

这个题只要稍微想一下,就可以知道这k个数都可以化成GCD(ALL k)*k[i]的形式。所以这个GCD一定是n的因子。我们只需要枚举n的因子,判断n/该因子的结果是否大于(1+2+....k),然后只需要把最后一个k变大点就可以了。

注意到n的范围为1e10,所以sqrt(n)的复杂度是可行的。n为1e10,所以大于1e6的k都是无解的。先加一个剪枝以免爆ll

5.代码实现

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<vector>
#include <time.h>
#include<string.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <db, db> pdd;

const int maxn = 2005;
const int Mod=1000000007;
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const double e=2.718281828459045235360287471352662;
const db PI = acos(-1);
const db ERR = 1e-10;

#define Se second
#define Fi first
#define pb push_back
ll n,k,flag;
vector<ll> v;
int main()
{
    //ios::sync_with_stdio(false);
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    cin>>n>>k;
    if(k>1000000)
    {
        cout<<-1<<endl;
        return 0;
    }
    ll pp=((1+k)*k)/2;
    if(n<pp)
    {
        cout<<-1<<endl;
        return 0;
    }
    for(ll i=1;i*i<=n;i++)
    {
        if(n%i==0)
        {
            v.pb(i);
            v.pb(n/i);
        }
    }
    int cnt=v.size();
    sort(v.begin(),v.end());
    for(int i=cnt-1;i>=0;i--)
    {
        if(n/v[i]>=pp)
        {
            for(ll j=1;j<=k-1;j++)
                printf("%lld ",j*v[i]);
            printf("%lld ",(n/v[i]-(k*(k-1))/2)*v[i]);
            return 0;
        }
    }
    cout<<-1<<endl;
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}

6.反思

注意一上来对数据范围的剪枝,很重要。

1.题目链接

http://codeforces.com/contest/803/problem/D

2.题面

D. Magazine Ad
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

The main city magazine offers its readers an opportunity to publish their ads. The format of the ad should be like this:

There are space-separated non-empty words of lowercase and uppercase Latin letters.

There are hyphen characters '-' in some words, their positions set word wrapping points. Word can include more than one hyphen.

It is guaranteed that there are no adjacent spaces and no adjacent hyphens. No hyphen is adjacent to space. There are no spaces and no hyphens before the first word and after the last word.

When the word is wrapped, the part of the word before hyphen and the hyphen itself stay on current line and the next part of the word is put on the next line. You can also put line break between two words, in that case the space stays on current line. Check notes for better understanding.

The ad can occupy no more that k lines and should have minimal width. The width of the ad is the maximal length of string (letters, spaces and hyphens are counted) in it.

You should write a program that will find minimal width of the ad.

Input

The first line contains number k (1 ≤ k ≤ 105).

The second line contains the text of the ad — non-empty space-separated words of lowercase and uppercase Latin letters and hyphens. Total length of the ad don't exceed 106 characters.

Output

Output minimal width of the ad.

Examples
input
Copy
4
garage for sa-le
output
Copy
7
input
Copy
4
Edu-ca-tion-al Ro-unds are so fun
output
Copy
10
Note

Here all spaces are replaced with dots.

In the first example one of possible results after all word wraps looks like this:

garage.
for.
sa-
le

The second example:

Edu-ca-
tion-al.
Ro-unds.
are.so.fun

3.题意

大概就是给你一段字符串,中间有空格和-,对于每个空格和-,都可以让之后的字符串转到下一行,问你将该字符串转为k行的最小宽度。

4.思路

很明显,答案具有二分的性质,如果长度n是允许的,那么大于n的一定是可行的,所以我们可以采取二分+验证答案的方式来nlogn解决这道题。

5.代码实现

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<vector>
#include <time.h>
#include<string.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <db, db> pdd;

const int maxn = 1e6+5;
const int Mod=1000000007;
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const double e=2.718281828459045235360287471352662;
const db PI = acos(-1);
const db ERR = 1e-10;

#define Se second
#define Fi first
#define pb push_back

char str[maxn];
bool check(int x, int len, int k)
{
	int cnt = 0, pre = 0;
	while (pre < len)
	{
		cnt++;
		int cur = pre + x;
		if (cur >= len)
			break;
		while (cur > pre && str[cur - 1] != ' ' && str[cur - 1] != '-')
			--cur;
		if (cur == pre)
			return 0;
		pre = cur;
	}
	return cnt <= k;
}
int main()
{
	int k;
	cin>>k;
	getchar();
    gets(str);
    int len = strlen(str);
    int l=0,r=len,mid;//找不到返回r+1
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(check(mid, len, k)) r=mid-1;
        else l=mid+1;
    }
    if(l==len+1)
        cout<<len<<endl;
    else
        cout<<l<<endl;
	return 0;
}

6.反思

看到nlogn的数据范围量,就要联想是否可以二分+验证答案。



猜你喜欢

转载自blog.csdn.net/qq_38891827/article/details/79978539