Codeforces Round #243 (Div. 2) B C

题目链接:
B. Sereja and Mirroring
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Let's assume that we are given a matrix b of size x × y, let's determine the operation of mirroring matrix b. The mirroring of matrix b is a2x × y matrix c which has the following properties:

  • the upper half of matrix c (rows with numbers from 1 to x) exactly matches b;
  • the lower half of matrix c (rows with numbers from x + 1 to 2x) is symmetric to the upper one; the symmetry line is the line that separates two halves (the line that goes in the middle, between rows x and x + 1).

Sereja has an n × m matrix a. He wants to find such matrix b, that it can be transformed into matrix a, if we'll perform on it several(possibly zero) mirrorings. What minimum number of rows can such matrix contain?

Input

The first line contains two integers, n and m (1 ≤ n, m ≤ 100). Each of the next n lines contains m integers — the elements of matrix a. The i-th line contains integers ai1, ai2, ..., aim (0 ≤ aij ≤ 1) — the i-th row of the matrix a.

Output

In the single line, print the answer to the problem — the minimum number of rows of matrix b.

Sample test(s)
input
4 3
0 0 1
1 1 0
1 1 0
0 0 1
output
2
input
3 3
0 0 0
0 0 0
0 0 0
output
3
input
8 1
0
1
1
0
0
1
1
0
output
2
题意:
给一个n x m的矩阵a,找出其中一个最小的矩阵b(矩阵宽度为n),通过镜面映像对称形成矩阵a。
思路:
折半递归,如样例3,以8 - 4 - 2的顺序递归。
注意:
这题我做的时候理解错题意了,结果一直卡到死。
以样例3为例,如果样例3是
0
1
1
0
0
1
那么这题答案应该是6而不是2,镜面映像必须是完整的。
AC代码:
#include<iostream>
using namespace std;
const int M = 220;
int nums[M][M], res, n,m;
void findans(int a)
{
    if(a % 2)
        return ;
    for(int i = 0, j = a - 1; i < a / 2; i++, j--)
        for(int k = 0; k < m; k++)
            if(nums[i][k] != nums[j][k])
                return ;
    res /= 2;
    findans(a / 2);
}
main()
{
    cin >> n >> m;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++)
            cin >> nums[i][j];
    res = n;
    findans(res);
    cout << res << endl;
}

C. Sereja and Swaps
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

As usual, Sereja has array a, its elements are integers: a[1], a[2], ..., a[n]. Let's introduce notation:

A swap operation is the following sequence of actions:

  • choose two indexes i, j (i ≠ j);
  • perform assignments tmp = a[i], a[i] = a[j], a[j] = tmp.

What maximum value of function m(a) can Sereja get if he is allowed to perform at most k swap operations?

Input

The first line contains two integers n and k (1 ≤ n ≤ 200; 1 ≤ k ≤ 10). The next line contains n integers a[1]a[2]...a[n] ( - 1000 ≤ a[i] ≤ 1000).

Output

In a single line print the maximum value of m(a) that Sereja can get if he is allowed to perform at most k swap operations.

Sample test(s)
input
10 2
10 -1 2 2 2 2 2 2 -1 10
output
32
input
5 10
-1 -1 -1 -1 -1
output
-1
题意:
可以通过k次交换,在长度为n的数列中找到累加和最大的子序列,输出累加和。
思路:
没想到这题居然用暴力的方法,我开始是先找的最大子序列和,后来想到这样做有bug,没想到用暴力的方法竟然可以跳过这个bug。
遍历所有的子段,然后将子段中的数和子段外的数交换,遍历所有结果。
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int M = 256;
int s[M], a[M], in[M], out[M];
main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
    {
        cin >> a[i];
        s[i] = s[i - 1] + a[i];
    }
    int ans = -1024;
    for(int i = 1; i <= n; i++)
        for(int j = i; j <= n; j++)
        {
            int sum = s[j] - s[i-1];
            int cnt1 = 0, cnt2 = 0;

            for(int k = i; k <= j; k++)
                in[cnt1++] = a[k];
            for(int k = 1; k < i; k++)
                out[cnt2++] = a[k];
            for(int k = j + 1; k <= n; k++)
                out[cnt2++] = a[k];
            sort(in, in + cnt1);
            sort(out, out + cnt2);
            int q = 0, p = cnt2 - 1;
            while(q < m && q < j - i + 1 && p >= 0 && in[q] < out[p])
                sum = sum - in[q++] + out[p--];
            ans = max(ans, sum);
        }
    cout << ans << endl;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值