[Offer收割]编程练习赛42
对局匹配
直接贪心
#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<functional>
#include<math.h>
//#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
void makedata() {
freopen("input.txt", "w", stdout);
cout << << endl; for(int i = ; i < ; i++) cout << << ' '; fclose(stdout);
} int a[]; int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
//makedata();
std::ios::sync_with_stdio(), cin.tie();
int n, k;
cin >> n >> k; for(int i = ; i < n; i++) cin >> a[i]; sort(a, a + n);
int ptr = , ans = ; while(ptr < n) {
if(ptr + < n && a[ptr + ] - a[ptr] <= k) {
ans++;
ptr += ;
} else ptr++;
} cout << ans << endl;
return ;
}
稀疏矩阵乘积
对应关系别搞乱就行了
#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<functional>
#include<math.h>
#include<set>
#include <list>
//#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII; int x[], y[], w[], b[][], c[][]; int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
std::ios::sync_with_stdio(), cin.tie();
int n, p, q;
int xx, yy, ww;
cin >> n >> p >> q;
for (int i = ; i < p; i++)cin >> x[i] >> y[i] >> w[i];
memset(b, , sizeof(b));
for (int i = ; i < q; i++) {
cin >> xx >> yy >> ww;
b[xx][yy] = ww;
}
memset(c, , sizeof(c));
for (int i = ; i < p; i++) {
for (int j = ; j <= n; j++) {
c[x[i]][j] += w[i] * b[y[i]][j];
}
}
for (int i = ; i <= n; i++) {
for (int j = ; j <= n; j++) {
if (c[i][j] != ) cout << i << ' ' << j << ' ' << c[i][j] << endl;
}
}
return ;
}
树上的等差数列
首先随便以某一个节点为根把树建起来。树上的一条路径可以看成是从某一个节点出发,在树结构上上升到某一个祖先节点,再下降到一个后代节点。记录father[x]为x节点的父节点,dep[x]为前两项为a[father[x]],a[x]的等差数列沿树结构向下最多能走的深度。枚举这个最高点r,把它的子节点按权值分类,枚举所有能构成等差数列的组合a1,a[r],a2,找到权值分别为a1和a2的子节点中dep值最大的点(且这两个点不为同一个点),那么产生了一个局部的最长等差数列l(a1)+1+l(a2),选出其中最大的输出。
#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<functional>
#include<math.h>
#include<set>
#include <list>
//#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII; map<int, VI> mp[];
int a[], father[], dep[];
VI G[]; void build(int x, int fa) {
father[x] = fa;
for (int i = ; i < G[x].size(); i++) {
int u = G[x][i];
if (u == fa) continue;
auto it = mp[x].find(a[u]);
if (it == mp[x].end()) mp[x][a[u]] = VI();
mp[x][a[u]].push_back(u);
build(u, x);
}
}
void calc(int x) {
if (dep[x] != ) return;
int d = a[father[x]] - a[x];
int aa = a[x] - d;
auto it = mp[x].find(aa);
if (it == mp[x].end()) {
dep[x] = ;
return;
}
int tmp = ;
for (int i = ; i < (*it).second.size(); i++) {
int u = (*it).second[i];
calc(u);
if (dep[u] + > tmp) tmp = dep[u] + ;
}
dep[x] = tmp;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
std::ios::sync_with_stdio(), cin.tie();
int n;
cin >> n;
for (int i = ; i <= n; i++) cin >> a[i];
for (int i = ; i < n; i++) {
int u, v;
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
build(, );
memset(dep, , sizeof(dep));
for (int i = ; i <= n; i++) calc(i);
int ans = ;
for (int i = ; i <= n; i++) {
for (auto itl = mp[i].begin(); itl != mp[i].end(); itl++) {
int lval = (*itl).first, ldep = , ldot = ;
for (int j = ; j < (*itl).second.size(); j++) {
if (dep[(*itl).second[j]] > ldep) {
ldep = dep[(*itl).second[j]];
ldot = (*itl).second[j];
}
}
int rval = * a[i] - lval, rdep = , rdot = ;
auto itr = mp[i].find(rval);
if (itr == mp[i].end()) {
if (ldep + > ans) ans = ldep + ;
continue;
}
for (int j = ; j < (*itr).second.size(); j++) {
if (dep[(*itr).second[j]] > rdep && (*itr).second[j] != ldot) {
rdep = dep[(*itr).second[j]];
rdot = (*itr).second[j];
}
}
if (ldep + + rdep > ans) ans = ldep + + rdep;
}
}
cout << ans << endl;
return ;
}
翻转字符串
可以用Splay树实现反转操作。首先根据整个字符串建树,对于每次操作(l,r),首先把l左边的字符旋转到根节点上,此时(l,r)位于根节点的右子树上;然后把r右边的字符旋转到根节点的右子树的树根,这样一来,就得到了只由(l,r)构成的一棵子树:根节点的右子树的左子树,对其添加一个lazy标记,最后对树进行一个前序遍历即可。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
using namespace std;
const int maxLength = ;
class Node{
public:
Node *child[];
char value;
int size;
bool flip;
Node(char c) :value(c), size(), flip(false){
child[] = child[] = NULL;
}
int getPosition()const{
return child[] ? child[]->size + : ;
}
void maintain();
void pushDown();
};
void Node::maintain(){
size = ;
if (child[]){
size += child[]->size;
}
if (child[]){
size += child[]->size;
}
}
void Node::pushDown(){
if (flip){
swap(child[], child[]);
for (int i = ; i < ; i++){
if (child[i]){
child[i]->flip ^= ;
}
}
flip = false;
}
}
class SplayTree{
public:
Node *root;
SplayTree(char *a, int n);
void build(Node *&node, char *begin, char *end);
void rotate(Node *&node, int direction);
void splay(Node *&node, int position);
void reverse(int begin, int end);
void traverse(Node *u);
void traverse();
};
SplayTree::SplayTree(char *a, int n){
build(root, a, a + n - );
}
void SplayTree::build(Node *&node, char *begin, char *end){
if (begin > end){
return;
}
char *middle = begin + (end - begin >> );
node = new Node(*middle);
build(node->child[], begin, middle - );
build(node->child[], middle + , end);
node->maintain();
} void SplayTree::rotate(Node *&node, int direction){
Node *child = node->child[direction ^ ];
node->child[direction ^ ] = child->child[direction];
child->child[direction] = node;
node->maintain();
child->maintain();
node = child;
}
void SplayTree::splay(Node *&node, int position){
node->pushDown();
if (node->getPosition() != position){
int d = node->getPosition() < position;
Node *node2 = node->child[d];
position -= d ? node->getPosition() : ;
node2->pushDown();
if (node2->getPosition() != position){
int d2 = node2->getPosition() < position;
position -= d2 ? node2->getPosition() : ;
splay(node2->child[d2], position);
if (d == d2){
rotate(node, d ^ );
}
else{
rotate(node->child[d], d);
}
}
rotate(node, d ^ );
}
}
void SplayTree::reverse(int begin, int end){
splay(root, begin);
splay(root->child[], end - begin + );
root->child[]->child[]->flip ^= ;
}
void SplayTree::traverse(Node *u){
if (!u){
return;
}
u->pushDown();
traverse(u->child[]);
if (u->value){
printf("%c", u->value);
}
traverse(u->child[]); }
void SplayTree::traverse(){
traverse(root);
}
int main(){
char s[maxLength] = "";
while (~scanf("%s", s + )){
int n = strlen(s + );
SplayTree splay(s, n + );
int k;
scanf("%d", &k);
for (int i = ; i < k; i++){
int begin, end;
scanf("%d%d", &begin, &end);
splay.reverse(begin + , end + );
}
splay.traverse();
printf("\n");
}
return ;
}
[Offer收割]编程练习赛42的更多相关文章
- hihocoder [Offer收割]编程练习赛4
描述 最近天气炎热,小Ho天天宅在家里叫外卖.他常吃的一家餐馆一共有N道菜品,价格分别是A1, A2, ... AN元.并且如果消费总计满X元,还能享受优惠.小Ho是一个不薅羊毛不舒服斯基的人,他希望 ...
- hihocoder [Offer收割]编程练习赛61
[Offer收割]编程练习赛61 A:最小排列 给定一个长度为m的序列b[1..m],再给定一个n,求一个字典序最小的1~n的排列A,使得b是A的子序列. 贪心即可,b是A的子序列,把不在b中的元素, ...
- [Offer收割]编程练习赛46
[Offer收割]编程练习赛46赛后题解 A.AEIOU 分析
- ACM学习历程—Hihocoder [Offer收割]编程练习赛1
比赛链接:http://hihocoder.com/contest/hihointerview3/problem/1 大概有一个月没怎么打算法了.这一场的前一场BC,也打的不是很好.本来Div1的A和 ...
- HihoCoder1670 : 比赛日程安排([Offer收割]编程练习赛41)(模拟)
描述 H国编程联赛中有N只队伍,编号1~N. 他们计划在2018年一共进行M场一(队)对一(队)的比赛. 为了让参赛队员能得到充分的休息,联赛组委会决定:每支队伍连续两场比赛之间至少间隔一天.也就是如 ...
- HihoCoder1642 : 三角形面积和([Offer收割]编程练习赛37)(求面积)(扫描线||暴力)(占位)
描述 如下图所示,在X轴上方一共有N个等腰直角三角形.这些三角形的斜边与X轴重合,斜边的对顶点坐标是(Xi, Yi). (11,5) (4,4) /\ /\(7,3) \ / \/\/ \ / /\/ ...
- [Offer收割]编程练习赛48
题目1 : 折线中点 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定平面上N个点P1, P2, ... PN,将他们按顺序连起来,形成一条折线. 请你求出这条折线的 ...
- [Offer收割]编程练习赛3 - 题目3 : 智力竞赛
智力竞赛 Problem's Link ---------------------------------------------------------------------------- Mea ...
- [Offer收割]编程练习赛5-1 小Ho的防护盾
#1357 : 小Ho的防护盾 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho的虚拟城市正在遭受小Hi的攻击,小Hi用来攻击小Ho城市的武器是一艘歼星舰,这艘歼星 ...
随机推荐
- Linux删除重复内容命令uniq笔记
针对文本文件,有时候我们需要删除其中重复的行.或者统计重复行的总次数,这时候可以采用Linux系统下的uniq命令实现相应的功能. 语法格式:uniq [-ic] 常用参数说明: -i 忽略大小写 - ...
- kvm之 virt-install工具命令详解
一.virt-install是一个命令行工具,它能够为KVM.Xen或其它支持libvrit API的hypervisor创建虚拟机并完成GuestOS安装:此外,它能够基于串行控制台.VNC或SDL ...
- 分享接口管理平台 eoLinker AMS 线上专业版V3.0,只为更好的体验,了解一下?
不知不觉中,eoLinker AMS从2016年上线至今已经三个年头,按照一年一个大版本的迭代计划,我们终于迎来了eoLinker AMS 专业版3.0. AMS产品也从最初专注于API文档管理,成长 ...
- Java语言输出HelloWorld
1.新建一个名为HelloWorld.txt的文本文件. 2.将HelloWorld.txt改为.java. 3.将HelloWorld.java用文本文件的方式打开,并输入代码. 4.打开命令行,进 ...
- Oracle 解决表死锁
select 'alter system kill session ''' || SID || ',' || SERIAL# || ''';' from ( select distinct a.sid ...
- JS控制全屏,监听退出全屏事件
实现方案 //进入全屏 function requestFullScreen(de) { if(de.requestFullscreen){ //W3C de.requestFullscreen(); ...
- python中的二进制、八进制、十六进制
python中通常显示和运算的是十进制数字. 一.python中的二进制 bin()函数,将十进制转换为二进制,0b是二进制的前缀.如: >>> bin(10) '0b1010' 二 ...
- Laravel 5
遍历数组@foreach($brand as $v) <a href='/brandss/seeshops?id={{$v->id}}'><img src="/pub ...
- oracle到mysql的导数据方式(适用于任意数据源之间的互导)
http://www.wfuyu.com/Internet/19955.html 为了生产库释放部份资源, 需要将API模块迁移到mysql中,及需要导数据. 尝试了oracle to mysql工具 ...
- LightOJ1234 Harmonic Number
/* LightOJ1234 Harmonic Number http://lightoj.com/login_main.php?url=volume_showproblem.php?problem= ...