1.统计数字

题目描述 Description

某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*109)。已知不相同的数
不超过10000 个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统
计结果。

输入描述 Input Description

第1行是整数n,表示自然数的个数。
第2~n+1 行每行一个自然数。

输出描述 Output Description

输出包含m行(m为n个自然数中不相同数的个数),按照自然数从小到大
的顺序输出。每行输出两个整数,分别是自然数和该数出现的次数,其间用一个空格隔开。

样例输入 Sample Input

8
2
4
2
4
5
100
2
100

样例输出 Sample Output

2 3
4 2
5 1
100 2

数据范围及提示 Data Size & Hint

【限制】
40%的数据满足:1<=n<=1000
80%的数据满足:1<=n<=50000
100%的数据满足:1<=n<=200000,每个数均不超过1 500 000 000(1.5*10^9)

(来自http://codevs.cn/problem/1164/)


  这道题没有什么特别的技术含量,排个序,再统计就行了

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cctype>
#include<map>
#include<set>
using namespace std;
template<typename T>
inline void readInteger(T& u){
char x;
while(!isdigit((x = getchar())));
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
}
int n;
int* list;
int main(){
freopen("count.in", "r", stdin);
freopen("count.out", "w", stdout);
readInteger(n);
list = new int[(const int)(n + )];
for(int i = ; i < n; i++){
readInteger(list[i]);
}
sort(list, list + n);
int counter = ;
int last = list[];
for(int i = ; i < n; i++){
if(list[i] != last){
cout<<last<<" "<<counter<<endl;
last = list[i];
counter = ;
}else counter++;
}
cout<<last<<" "<<counter<<endl;
return ;
}

统计数字


2.矩阵取数游戏

题目描述 Description

【问题描述】
帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m 的矩阵,矩阵中的每个元素aij均
为非负整数。游戏规则如下:
1. 每次取数时须从每行各取走一个元素,共n个。m次后取完矩阵所有元素;
2. 每次取走的各个元素只能是该元素所在行的行首或行尾;
3. 每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分= 被取走的元素值*2i,
其中i 表示第i 次取数(从1 开始编号);
4. 游戏结束总得分为m次取数得分之和。
帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。

输入描述 Input Description

第1行为两个用空格隔开的整数n和m。
第2~n+1 行为n*m矩阵,其中每行有m个用单个空格隔开的非负整数。

输出描述 Output Description

输出 仅包含1 行,为一个整数,即输入矩阵取数后的最大得分。

样例输入 Sample Input

2 3
1 2 3
3 4 2

样例输出 Sample Output

82

数据范围及提示 Data Size & Hint

样例解释

第 1 次:第1 行取行首元素,第2 行取行尾元素,本次得分为1*21+2*21=6
第2 次:两行均取行首元素,本次得分为2*22+3*22=20
第3 次:得分为3*23+4*23=56。总得分为6+20+56=82

【限制】
60%的数据满足:1<=n, m<=30, 答案不超过1016
100%的数据满足:1<=n, m<=80, 0<=aij<=1000

(来自http://codevs.cn/problem/1166/)


  这道题首先一看数据范围就知道要用高精度,最好用上万进制以免其他地方处理不当导致TLE,
接着可以发现每一行取出来的得分和其他行没有关系,就可以分开计算,最后把所有行加起来就行了。
至于这个计算,很容易想到dp,用f[i][j]表示第i次取数,左边取了j个,或者f[i][j]表示左边取了i个,
右边取了j个,总之能表示出左右分别取了多少个就行了。
  就说第一种的方程
  f[i][j] = max(f[i - 1][j - 1] + a[l][j], f[i - 1][j] + a[l][m - i + j - 1]);
  我做的时候稍微有点不一样,但是思路还是一样的,仍然很容易理解
 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#include<map>
using namespace std;
typedef bool boolean;
template<typename T>
inline void readInteger(T& u){
char x;
while(!isdigit((x = getchar())));
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
}
typedef class HP{
public:
int w[];
HP(){
memset(w, , sizeof(w));
}
HP(long long x){
memset(w, , sizeof(w));
if(x == ) w[] = ;
while(x > ){
w[++w[]] = x % ;
x /= ;
}
}
HP operator *(int x){
HP result;
result[] = w[] + ;
for(int i = ; i <= w[] + ; i++){
result[i] += w[i] * x;
result[i + ] += result[i] / ;
result[i] %= ;
}
while(result[result[]] == && result[] > ) result[]--;
return result;
}
HP operator +(HP another){
HP result;
result[] = max(w[], another[]) + ;
for(int i = ; i < result[]; i++){
result[i] += w[i] + another[i];
result[i + ] += result[i] / ;
result[i] %= ;
}
while(result[result[]] == && result[] > ) result[]--;
return result;
}
boolean operator <(HP another) const{
if(w[] != another[]) return w[] < another[];
for(int i = w[]; i >= ; i--){
if(w[i] != another[i]) return w[i] < another[i];
}
return false;
}
int& operator [](int pos){
return w[pos];
}
}HP;
int matrix[][];
HP result[];
HP pow_2[];
int n, m;
HP f[][][];
inline void solve(int lines){
memset(f, , sizeof(f));
f[][][] = pow_2[] * matrix[lines][];
f[][][] = pow_2[] * matrix[lines][m];
for(int i = ; i <= m; i++){
for(int j = ; j < i; j++){
HP temp = max(f[i - ][j][], f[i - ][j - ][]);
f[i][j][] = temp + pow_2[i] * matrix[lines][j + ];
f[i][j][] = temp + pow_2[i] * matrix[lines][m - i + j + ];
}
}
for(int i = ; i < m; i++){
for(int j = ; j < ; j++){
result[lines] = max(result[lines], f[m][i][j]);
}
}
}
ostream& operator <<(ostream& out, HP& x){
int buf[];
for(int i = x[]; i >= ; i--){
if(i != x[]){
memset(buf, , sizeof(buf));
int c = x[i];
while(c > ){
buf[++buf[]] = c % ;
c /= ;
}
for(int i = ; i >= ; i--)
putchar(buf[i] + '');
}else{
printf("%d",x[i]);
}
}
return out;
}
inline void init(){
readInteger(n);
readInteger(m);
for(int i = ; i <= n; i++){
for(int j = , x; j <= m; j++){
readInteger(matrix[i][j]);
}
}
pow_2[] = HP();
for(int i = ; i <= m + ; i++)
pow_2[i] = pow_2[i - ] * ;
}
HP ans;
int main(){
freopen("game.in", "r", stdin);
freopen("game.out", "w", stdout);
init();
ans[] = ;
for(int i = ; i <= n; i++){
solve(i);
ans = ans + result[i];
}
cout<<ans;
return ;
}

矩阵取数游戏


3.树网的核


  思考一下,是不是并没有想出dp之类的十分高效的算法?再看看数据范围,n最大才300,不怕,暴力都很容易过(当然,
这是对于现在的电脑)。不过有一点还是要清楚,一定得找出一条直径来,接着在上面一段一段地去枚举。
  需要枚举所有的直径吗?不需要,画画图就知道了
  接着还有,怎么提高枚举的效率?首先选一段的偏心距不会多于选一个节点作为核的偏心距,而且这一道题也不要求输出
方案,所以能选多少就选多少,避免很多排列。
  求直径还不清楚的话,我就再说一下,首先随便从一个点开始dfs找出一个离它最远的点,再从这个点开始dfs找出一个离它
最远的点,然后这两个点的距离就是直径的长度,注意还要记录路径
 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#include<vector>
using namespace std;
typedef bool boolean;
template<typename T>
inline void readInteger(T& u){
char x;
while(!isdigit((x = getchar())));
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
}
typedef class Edge{
public:
int end;
int next;
int v;
Edge(const int end = , const int next = , const int v = ):end(end),next(next), v(v){}
}Edge;
int ce;
int *h;
Edge* edge;
inline void addEdge(int from, int end, int v){
edge[++ce] = Edge(end, h[from], v);
h[from] = ce;
}
int* buf;
int imn;
int maxdis;
int *rd;
int *brd;
boolean *visable;
void dfs(int* path, int node, int dis, int last, int d){
if(path != NULL){
buf[++buf[]] = node;
if(buf[] != )
brd[buf[] - ] = d;
}
if(dis > maxdis){
maxdis = dis;
if(path != NULL){
memcpy(path, buf, sizeof(int) * (buf[] + ));
memcpy(rd, brd, sizeof(int) * (buf[] + ));
}
imn = node;
}
for(int i = h[node]; i != ; i = edge[i].next){
int e = edge[i].end;
if(e == last) continue;
if(!visable[e]) continue;
dfs(path, e, dis + edge[i].v, node, edge[i].v);
}
if(path != NULL) buf[]--;
}
int n, s;
int *road;
inline void init(){
readInteger(n);
readInteger(s);
edge = new Edge[(const int)(n * )];
h = new int[(const int)(n + )];
buf = new int[(const int)(n + )];
road = new int[(const int)(n + )];
rd = new int[(const int)(n + )];
brd = new int[(const int)(n + )];
memset(h, , sizeof(int) * (n + ));
memset(buf, , sizeof(int) * (n + ));
visable = new boolean[(const int)(n + )];
memset(visable, true, sizeof(boolean) * (n + ));
for(int i = , a, b, v; i < n; i++){
readInteger(a);
readInteger(b);
readInteger(v);
addEdge(a, b, v);
addEdge(b, a, v);
}
}
inline void solve(){
dfs((int*), , , , );
maxdis = ;
dfs(road, imn, , , );
buf[] = ;
maxdis = ;
int len = ;
int l = , r = ;
int cn = ;
int result = 0xfffffff;
visable[road[]] = false;
while(r <= road[] && l <= r){
while(r < road[] && (len + rd[r] <= s)){
len += rd[r];
r++;
cn++;
visable[road[r]] = false;
}
int p = ;
for(int i = l; i <= r; i++){
maxdis = ;
dfs((int*), road[i], , , );
p = max(p, maxdis);
}
if(p < result) result = p;
visable[road[l]] = true;
cn--;
if(cn > )
len -= rd[l];
else if(r < road[]){
len = ;
r++;
visable[road[r]] = false;
}
l++;
}
cout<<result;
}
int main(){
freopen("core.in", "r", stdin);
freopen("core.out", "w", stdout);
init();
solve();
return ;
}

树网的核

noip2007部分题的更多相关文章

  1. 【NOIP2007提高组】字符串展开

    [题外话]这道题纯粹考验耐心,某些经常调程序调到摔键盘的人可以尝试 [题外话2]除了考耐心以外完全没有什么难点 [题外话3]也许会稍微恶心一点? [题外话4]其实我是在别人军训的时候滚来更博客的简直2 ...

  2. NOIP初赛:完善程序做题技巧

    最近写的文章好像还很多的.那么今天我们来讨论NOIP初赛的题型--完善程序.完善程序相对是比较难的题目了.全卷100分,完善程序占了大概26分,占比非常大.如果和英语考试试卷做比较,相当于首字母填空( ...

  3. NOIP水题合集[3/未完待续]

    NOIP2008pj传球游戏 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球, ...

  4. vijos1431[noip2007]守望者的逃离(背包动规)

    描述 恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变.守望者 在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上.为了杀死守望者,尤迪安开始对这 个荒岛施咒,这座岛很快就会 ...

  5. 备战NOIP每周写题记录(一)···不间断更新

    ※Recorded By ksq2013 //其实这段时间写的题远远大于这篇博文中的内容,只不过那些数以百记的基础题目实在没必要写在blog上; ※week one 2016.7.18 Monday ...

  6. [BZOJ1999][codevs1167][Noip2007]Core树网的核

    [BZOJ1999][codevs1167][Noip2007]Core树网的核 试题描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(t ...

  7. noip2007提高组题解

    题外话:这一年的noip应该是最受大众关心的,以至于在百度上输入noip第三个关键字就是noip2007.主要是由于这篇文章:http://www.zhihu.com/question/2110727 ...

  8. NOIP前刷题记录

    因为本蒻实在太蒻了...对于即将到来的NOIP2018ssfd,所以下决心要把自己近期做过的题目(衡量标准为洛谷蓝题难度或以上)整理一下,归归类,简单地写一下思路,就当作自己复习了吧qwq 本随笔持续 ...

  9. OI 刷题记录——每周更新

    每周日更新 2016.05.29 UVa中国麻将(Chinese Mahjong,Uva 11210) UVa新汉诺塔问题(A Different Task,Uva 10795) NOIP2012同余 ...

随机推荐

  1. 删除RAC集群节点

    删除GRID集群节点:参考oracle database 11g RAC手册(第二版) 目前GRID集群中节点信息:[grid@node1 ~]$ olsnodesnode1node2node3nod ...

  2. RFQ 、IFB、RFP 、RFI的区别是什么

    询价类型 信息索取书 RFI 报价申请书 RFQ 建议要求书 RFP 投标邀请书 IFB 目的 获得与产品服务供应商相关信息 取得供应商对所需产品.服务或服务的承诺 要求供应商对需求提出最好解决方案建 ...

  3. 币安Binance API

    本文介绍币安Binance API General API Information The base endpoint is: https://api.binance.com All endpoint ...

  4. 2018/03/19 每日一个Linux命令 之 touch

    touch 英文翻译为 触碰 很形象 touch [文件] 就像我就碰你一下,什么都不干..... 如果没有这个文件则我就新建这个文件 会修改这个文件的最后修改时间 没有的话则会产生一个0字节大小的空 ...

  5. Intellij Idea常用配置设置

    1.配置Intellij Idea的配置文件从默认c盘转移到其他盘符 找到Intellij idea的安装文件,在bin目录下找到idea.properties配置文件,如下把Idea的配置文件夹和I ...

  6. 正则验证ip

    用python爬获取这样一条数据: <td class="ip" id="ip"><p style="display: none;& ...

  7. 使用Python2.7 GET Onenet平台的数据

    效果 代码 # -*- coding: utf-8 -*- """ ------------------------------------------------- F ...

  8. [LeetCode] 867. Transpose Matrix_Easy

    Given a matrix A, return the transpose of A. The transpose of a matrix is the matrix flipped over it ...

  9. iOS 自定义日志输出

    在做iOS开发过程中,我们经常需要输出日志来查看某些数据是否打印出来,或者查看查个类是否被调用了. 系统默认的是NSLog(@"xxxx %d",1) ,但如果该APP要发布到商店 ...

  10. Android弹性滑动的三种实现方式

    引言 上一篇文章我们介绍了实现弹性滑动的三种方式,但仅仅是给出了代码片段和方法理论.今天我们结合一个具体的例子来谈一下如何使用这三种方法来实现弹性滑动.今天我们的例子是仿IOS的下拉操作,我们知道An ...