码迷,mamicode.com
首页 > 其他好文 > 详细

Day two

时间:2016-07-14 15:27:39      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:

A. Pasha and Stick

http://codeforces.com/problemset/problem/610/A

Pasha has a wooden stick of some positive integer length n. He wants to perform exactly three cuts to get four parts of the stick. Each part must have some positive integer length and the sum of these lengths will obviously be n.

Pasha likes rectangles but hates squares, so he wonders, how many ways are there to split a stick into four parts so that it’s possible to form a rectangle using these parts, but is impossible to form a square.

Your task is to help Pasha and count the number of such ways. Two ways to cut the stick are considered distinct if there exists some integer x, such that the number of parts of length x in the first way differ from the number of parts of length x in the second way.

Input
The first line of the input contains a positive integer n (1?≤?n?≤?2·109) — the length of Pasha’s stick.

Output
The output should contain a single integer — the number of ways to split Pasha’s stick into four parts of positive integer length so that it’s possible to make a rectangle by connecting the ends of these parts, but is impossible to form a square.

Sample Input
Input
6
Output
1
帕夏喜欢长方形但讨厌正方形(呵呵),所以他想知道,有多少种方法将一根木棒分成四部分,然后用这四部分组成一个矩形,不能组成一个正方形。
你的任务是帮助帕夏和计算有多少种分割的方法。两种方法来切割的棒被认为是不同的,如果存在一些整数X,这样,在第一种方式的长度x的部分的数量不同于第二种方式的长度x的数量。
输入
输入的第一行包含一个正整数N(1≤N≤2·109)-帕夏的棒的长度。
输出
输出可分割的方法总数。

题目很水是真的。主要问题是看懂题目,目前的水平独立看懂英文题目是有很大的困难的。
首先判断输入的木棒的长度是不是偶数,如果是奇数则没有任何一种方法可以将它分割然后组成一个矩形。然后可通过简单的手写的例子找规律,如:

n=2020/2=10(1,9)(2,8)(3,7)(4,6)n=2220/2=11(1,10)(2,9)(3,8)(4,7)(5,6)x,yx+y=n/2,x!=y;

#include<stdio.h>

int f(int n){
    int m;
    if(n%2){     //如果输入为奇数,则直接返回0
        return 0;
    }
    else{
        m = n/2; 
        if(m%2){
            return (m-1)/2;
        }
        else{
            return m/2-1;
        }
    }
}
int main(){
    int n;
    scanf("%d",&n);
    printf("%d\n",f(n));
    return 0;
}

B. Vika and Squares

http://codeforces.com/problemset/problem/610/B

Vika has n jars with paints of distinct colors. All the jars are numbered from 1 to n and the i-th jar contains ai liters of paint of color i.

Vika also has an infinitely long rectangular piece of paper of width 1, consisting of squares of size 1?×?1. Squares are numbered 1, 2, 3 and so on. Vika decided that she will start painting squares one by one from left to right, starting from the square number 1 and some arbitrary color. If the square was painted in color x, then the next square will be painted in color x?+?1. In case of x?=?n, next square is painted in color 1. If there is no more paint of the color Vika wants to use now, then she stops.

Square is always painted in only one color, and it takes exactly 1 liter of paint. Your task is to calculate the maximum number of squares that might be painted, if Vika chooses right color to paint the first square.

Input
The first line of the input contains a single integer n (1?≤?n?≤?200?000) — the number of jars with colors Vika has.

The second line of the input contains a sequence of integers a1,?a2,?…,?an (1?≤?ai?≤?109), where ai is equal to the number of liters of paint in the i-th jar, i.e. the number of liters of color i that Vika has.

Output
The only line of the output should contain a single integer — the maximum number of squares that Vika can paint if she follows the rules described above.

Examples
input
5
2 4 2 3 3
output
12
input
3
5 5 5
output
15
input
6
10 10 10 1 10 10
output
11

这道题的意思很简单:n个数字,每个数字代表有ai升油漆,问从哪个数字开始,一遍一遍刷油漆,能够用掉最多的油漆。
最开始的想法可以转化为求两个最小值之间的最大距离,手推几组数据可以发现这几组数据都是从最小值之间的最大长度开始算起的。 然后,最小值 * n+最小值之间的最大长度=能够用掉的最多油漆。
代码如下:

#include<bits/stdc++.h>   //这个头文件包含以下等等C++中包含的所有头文件
using namespace std;
const int  mm = 1<<30;
long long  f[200010],z[200010]; //f数组存数值大小,z数组存两个最小值之间的距离

int main(){
    int n;
    long long min = mm;
    cin>>n;
    for(int i = 0;i < n;i++){
        cin>>f[i];
        min = min>f[i]?f[i]:min;     //先找到最小的值mix
    }
    int r = 0,flag = 0,j = 0;
    for(i = 0;i < n;i++){
        if(min == f[i]){             //如果等于最小值
            if(j == 0){              //第一个最小值与前边界的距离
                z[j++] = i;
                r = i;               //储存当前最小值的下标
            }
            else{                    
                z[j++] = i-r-1;     //与前一个最小值之间的距离
                r = i;
            }
        }
        flag = j;
    }   
    z[0] += n-r-1;          //将最后一个最小值与后边界的距离加到第一个最小值与前边界的距离上。
    sort(z,z+flag);         //升序排序
    cout<<min*n+z[flag-1]<<endl; //最小值 * n+最小值之间的最大长度=能够用掉的最多油漆
    return 0;
}

但是这个代码在vc上编译通过了,在网站上却显示结果错误,然后有了另外一种思路。先找出数量最少的油漆数,再全部扫描,记录上所有数量最少的油漆种类。通过一些简单的例子可以发现要能够刷尽可能多的方块,第一个方块刷的都是数量最少的油漆的后一种油漆,也就是说从记录下来的所有数量都是最少的油漆种类中依次扫描,每次都能得到一个所用到的最大油漆数,然后取最大值
#include<bits/stdc++.h> //这个头文件包含以下等等C++中包含的所有头文件,这个东西炒鸡厉害!!!
如果数据超过整形数据表示范围,可以用long long型,1LL?n 也可将整型n转换为long long型
使用了vector容器的一下基本操作

代码如下:

#include<bits/stdc++.h>        //这个头文件包含以下等等C++中包含的所有头文件
using namespace std;

int min = 1e9+5,ans = 0;
int a[200005];
vector<int> P;
int main(){
    int n;
    scanf("%d",&n);
    for(int i = 1;i <= n;i++)
        scanf("%d",&a[i]);
    for(int i = 1;i <= n;i++){ //先找到最小的值min
        if(Min>=a[i]){
            Min = a[i];
            ans = i;
        }
    }
    int first = 0;
    for(int i = 1;i <= n;i++){       
        if(a[i] == Min)       //如果等于最小值
            P.push_back(i);
    }
    P.push_back(P[0]+n);
    long long tmp = 0;
    for(int i=1;i<P.size();i++)
        tmp = max(tmp,1LL*P[i]-1LL*P[i-1]-1LL);      //转换为long long型
    printf("%lld\n",1LL*n*Min+1LL*tmp);
}

C - USB Flash Drives

http://codeforces.com/problemset/problem/609/A

Sean is trying to save a large file to a USB flash drive. He has n USB flash drives with capacities equal to a1,?a2,?…,?an megabytes. The file size is equal to m megabytes.

Find the minimum number of USB flash drives needed to write Sean’s file, if he can split the file between drives.
Input
The first line contains positive integer n (1?≤?n?≤?100) — the number of USB flash drives.
The second line contains positive integer m (1?≤?m?≤?105) — the size of Sean’s file.
Each of the next n lines contains positive integer ai (1?≤?ai?≤?1000) — the sizes of USB flash drives in megabytes.
It is guaranteed that the answer exists, i. e. the sum of all ai is not less than m.

Output
Print the minimum number of USB flash drives to write Sean’s file, if he can split the file between drives.
3
5
2
1
3
Output
2
Input
3
6
2
3
2
Output
3

看懂题目之后没什么好说的。就是有一个一定大小的文件,然后给你若干个大小不一样的U盘,让你选择尽可能少的U盘取存储这些文件。将U盘大小降序排序,先选择最大的,若文件还有未储存的,则继续选择次大的U盘

#include<stdio.h>
#include<iostream>
#include<cmath>
#include<algorithm> 
using namespace std;

int main(){
    int i,a[105];;
    int n;
    cin>>n;        //U盘总数量
    long long m;
    cin>>m;       //文件总大小
    for(i = 0;i < n;i++){ //各个U盘大小
        cin>>a[i];
    }
    sort(a,a+n);     //从小到大排序
    long long sum = 0;         
    for(i = 1;i <= n;i++){  //用到U盘最少的数量
        sum += a[n-i];  
        if(sum >= m){
            cout<<i<<endl;  
            break;  
        }  
    }  
    return 0;  
}

D - The Best Gift

http://codeforces.com/problemset/problem/609/B

Emily’s birthday is next week and Jack has decided to buy a present for her. He knows she loves books so he goes to the local bookshop, where there are n books on sale from one of m genres.
In the bookshop, Jack decides to buy two books of different genres.

Based on the genre of books on sale in the shop, find the number of options available to Jack for choosing two books of different genres for Emily. Options are considered different if they differ in at least one book.

The books are given by indices of their genres. The genres are numbered from 1 to m.

Input
The first line contains two positive integers n and m (2?≤?n?≤?2·105,?2?≤?m?≤?10) — the number of books in the bookstore and the number of genres.
The second line contains a sequence a1,?a2,?…,?an, where ai (1?≤?ai?≤?m) equals the genre of the i-th book.
It is guaranteed that for each genre there is at least one book of that genre.

Output
Print the only integer — the number of ways in which Jack can choose books.
It is guaranteed that the answer doesn’t exceed the value 2·109.

Sample Input
Input
4 3
2 1 3 1
Output
5
Input
7 4
4 2 3 1 2 4 3
Output
18

Jack准备给Emily买两本书作为生日礼物,书店有很多种不同类型的书,每种类型的书有若干本,Jack要在这些书中间选两本不同类型的送给Emily,求Jack有多少种选择书籍的方法
思路很简单。按照书籍类型一次扫描,然后相乘相加即可

#include<bits/stdc++.h>   //这个头文件包含以下等等C++中包含的所有头文件
using namespace std;

int h[15];        //记录每种类型书籍的数量
int main(){
    int n,m;
    scanf("%d%d",&n,&m);       //在书店里书籍的数量和类型的数量
    for(int i = 1;i <= n;i++){ //第i本书的体裁
        int x;scanf("%d",&x);
        h[x]++;
    }
    long long sum = 0;
    for(int i = 1;i <= m;i++)
        for(int j = i+1;j <= m;j++)
            sum += h[i]*h[j];
    cout<<sum<<endl;
}

总结

写博客的时候再看题目和代码就觉得很简单,但是在自己最开始做题的过程中也是遇到过很多让我非常痛苦的小细节,比如没有符合标准输入输出、所有的情况考虑不完整、没有考虑到数据范围、还有就是觉得代码正确但硬是提交错误的一系列。希望自己能够在这个暑假中坚持下来,相信只要花费了时间好好练习病总结错误总会有进步的,Fighting!

Day two

标签:

原文地址:http://blog.csdn.net/a1128o/article/details/51907137

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!