51nod 8-14

题目来源: CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
 收藏
 关注

一天,欧姆诺诺姆来到了朋友家里,他发现了许多糖果。有蓝色和红色两种。他知道每颗红色糖果重Wr克,每颗蓝色糖果重Wb克。吃一颗蓝色糖果会给他带来Hb的欢乐值,吃一颗红色糖果会给他带来Hr的欢乐值。

欧姆诺姆最多只能吃C克的糖果,而且每一颗糖果不能只吃一半。现在他想通过吃蓝色和红色的糖果来获得最大的欢乐值。

样例解释:每一种糖果吃两颗即可。

Input
单组测试数据。
输入占一行有四个整数C,Hr,Hb,Wr,Wb (1≤C,Hr,Hb,Wr,Wb≤10^9).
Output
输出最大可能获得的欢乐值。
Input示例
样例输入1
10 3 5 2 3
Output示例
样例输出1
16
这道题嗯,暴力贼好想,枚举一下其中一个取多少个即可,贪心:性价比小的少去点,大的多去点。评论区证明了性价比小的取的个数不会超过sqrt(C)个。
枚举喽
#include<stdio.h>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
bool flag;
ll C,Hr,Hb,Wr,Wb,num_red,num_blue;
long long ans=0;
int main()
{
    scanf("%lld %lld %lld %lld %lld",&C,&Hr,&Hb,&Wr,&Wb);
    if(1.0*Hr/Wr>1.0*Hb/Wb) flag=1;
    int sqr=sqrt(C*1.0); 
    for(int i=0;i<=sqr;i++)
    {
             num_blue=i;
             num_red=(C-i*Wb)/Wr;
             if(C-i*Wb<0) continue; 
             ans=max(ans,(long long)num_blue*Hb+num_red*Hr);
             num_red=i;
             num_blue=(C-i*Wr)/Wb;
             if(C-i*Wr<0) continue;
             ans=max(ans,(long long)num_blue*Hb+num_red*Hr);
    }
    printf("%lld
",ans);
 } 
小C偶然发现了一个奇妙的n个点的多边形。现在你需要给外圈的边标记上1~n-1,里圈的边也标记上1~n-1,使得对于一个外圈相邻点与中间点构成的三角形的边权之和都相等。
图中带三角形的三个点构成的三角形的边权都要相等。
你需要输出一种标记方案。(如果不存在就输出0)
Input
一共一行。
第一行,有一个n(4<=n<=1,000,000)。
Output
第一行n-1个数表示顺时针方向外圈的的边权(ai)。
第二行n-1个数表示顺时针方向里圈的的边权(bi)。
并且a1和b1,b2构成第1个三角形,a2和b2,b3构成第2个三角形....,an-1和bn-1,b1构成第n-1个三角形。具体请参看样例!
Input示例
4
Output示例
1 2 3
2 3 1
这题数学+乱搞,我都不知道评测机还得判你的输出合不合法~~
边长总和为3*(n-1)*n/2,所以每个三角形的边长为3*n/2,然后就是构造了。
受到样例的启发,我们把最外圈按照1~n-1填上,然后1的那个的左边填上n-1,最大搭最小嘛,然后递推...
#include<stdio.h>
#include<algorithm>
using namespace std;
void work()
{
    int n;
    scanf("%d",&n);
    if(n%2==1)
    {
        puts("0");
        return ;
    }
    printf("%d",1);
    for(int i=2;i<n;i++) printf(" %d",i);
    printf("
");
    int sum=n*3/2;
    int t=sum-(n-1)-1;
    for(int i=1;i<n-1;i++)
    {
        printf("%d ",t);
        t=sum-t-i;
     }
    puts("1"); 
}
int main()
{
    work();
}
基准时间限制:1.5 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
 收藏
 关注
数据流统计功能上线后,为51nod提升用户体验做出了很大的贡献。但是新问题随之而来,夹克老爷还想知道在一个窗口内,访问次数最多用户(即窗口内的众数)。如果有多个众数,取用户ID最小的一个。(窗口的意思是一个固定长度的区间!)
 
(因为数据流是实时的、在线的,所以不允许使用离线算法^_^)
Input
第一行为整数n, k。(1 <= n <= 5 * 10^6,1 <= k <= 1000)
n代表有多少次操作,k代表窗口大小。

接下来的n行,每行代表一次操作。每行第一个整数为操作数。

操作数1:用户访问
输入格式: <1, id>
用户ID为[0, INT_MAX]闭区间内的整数。代表拥有此ID的用户对网站进行了一次访问,窗口进行相应移动。

操作数2:询问众数
输入格式:<2>
输出窗口内的众数,如果有多个,输出ID最小的那个。

p.s. 对于询问众数的操作,窗口保证不空
p.s.s. 对于询问众数的操作,窗口可能不满
Output
对于询问众数的操作,每行输出一个整数。
Input示例
10 5
1 2
1 1
1 2
1 1 
1 2
1 1
2
1 3
1 3
2
Output示例
1
1
stl中的map,set,queue的糅杂,set在这里一部分感觉当一个priority_queue在用,方便,还支持一堆操作。
这里的set还要用mutiset,坑
顺便第一个表示出现的次数,第二个表示数字
Map表示一个数字出现了几次
#include<stdio.h>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
using namespace std;
struct note{
    int num,val;
    friend bool operator <(note a,note b)
    {
        return(a.num==b.num? a.val>b.val:a.num<b.num);
    }
};
multiset<note> setp;
map<int,int> Map;
queue<int> que;
int n,k,Mode,val;
int main()
{
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&Mode);
        if(Mode==1)
        {
            scanf("%d",&val);
            val++;
            if(que.size()>=k)
            {
                int p=que.front();
                setp.erase(setp.find((note){Map[p],p})); 
                Map[p]--;
                setp.insert((note){Map[p],p});
                que.pop();
            }
            if(Map[val])setp.erase(setp.find((note){Map[val],val}));
            Map[val]++;
            setp.insert((note){Map[val],val});
            que.push(val);
        }else
        {
            printf("%d
",(*setp.rbegin()).val-1);
        }
    }
}
原文地址:https://www.cnblogs.com/dancer16/p/7360647.html