预计分数:100+0+60=160

实际分数:100+0+60=160

mmpT1数据错了。。。

T1遭遇

题目描述

你是能看到第一题的 friends呢。

—— hja

?座楼房,立于城中 。

第?座楼,高度 ℎ?。

你需要一开始选择座楼,跳。 在第 ?座楼准备跳需要 ??的花费。 每次可以跳到任何一个还没有过的楼上去。但是代价,另外一座楼的代价是两高度差绝对值 ,最后一次从楼上跳到地面不需 要代价(只能跳到地上一次)。为在不超过 要代价(只能跳到地上一次)。为在不超过 ?的情况下,最多跳几次楼。 (一座楼 只能 跳一次 ,且每次 跳楼 都要 计算 准备 的花费 )

输入输出格式

输入格式:

第一行个整数 ?,代表 楼的数量。

接下来一行 ?个整数代表 ??。

接下来一行 ?个整数代表 ℎ?。

最后一行个整数 ?。

输出格式:

一行个整数 代表答案 。

输入输出样例

输入样例#1: 复制

4
3 5 4 11
2 1
3 17
输出样例#1: 复制

3
【样例解释】
从1号楼跳到 2号楼再跳到 3号楼是一种 可行 的方案 。

说明

对于 30%的数据, 1≤?≤5。

对于另外 20%的数据,所有 ℎ?相同。

对于另外 20%的数据, ??=0。

P104 zhx 遭遇

第 3 页 共 6 页

对于 100%的数据, 1≤?≤50,1≤??,ℎ?≤106,1≤?≤107。

不会做,不过70分的算法貌似比较好想

但是h相等的情况貌似写炸了,。。。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<ctime>
using namespace std;
const int MAXN=;
const int INF=0x7ffff;
inline int read()
{
char c=getchar();int flag=,x=;
while(c<''||c>'') {if(c=='-') flag=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-,c=getchar();return x*flag;
}
int n,bg;//kashi
struct node
{
int c;
int h;
}a[MAXN];
int comp(const node &a,const node &b)
{
return a.c<b.c;
}
int comp2(const node &a,const node &b)
{
return a.h<b.h;
}
int ans=;
int vis[MAXN];
int T;
int dfs(int now,int spend,int have)
{
ans=max(ans,have);
for(int i=;i<=n;i++)
{
if(vis[i]==&&spend+a[i].c+abs(a[now].h-a[i].h)<=T)
{
if(clock()-bg>=)
{
printf("%d",ans);
exit();
}
vis[i]=;
dfs(i,spend+a[i].c+abs(a[now].h-a[i].h),have+);
vis[i]=;
}
}
}
int flagh=;//高度是否相同
int flagc=;//花费是否都为0
inline void solvec()//花费都为0
{
sort(a+,a+n+,comp2);
for(int i=;i<=n;i++)//从每一个点往后跳
{
int nowjump=;
int nowspend=;
for(int j=i+;j<=n;j++)
{ if(abs(a[j].h-a[j-].h)+nowspend<=T)
{
nowspend=abs(a[j].h-a[j-].h)+nowspend;
nowjump+=;
}
ans=max(ans,nowjump+);
}
}
}
inline void solveh()
{
int nowjump=;
int nowspend=-;
if(a[].c<=T)
{
nowspend=a[].c;
for(int i=;i<=n;i++)
if(nowspend+a[i].c<=T)
nowjump++,nowspend+=a[i].c;
} if(nowspend!=-) ans=max(ans,nowjump+);
}
int main()
{
// freopen("meet.in","r",stdin);
// freopen("meet.out","w",stdout);
bg=clock();
n=read();
for(int i=;i<=n;i++) a[i].c=read();
for(int i=;i<=n;i++) a[i].h=read();
T=read();
sort(a+,a+n+,comp);
for(int i=;i<=n;i++)
if(a[i].c!=) flagc=;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(a[i].h!=a[j].h&&i!=j)
flagh=;
if(flagc) solvec();
if(flagh) solveh(); for(int i=;i<=n;i++)
if(a[i].c<=T)
vis[i]=,dfs(i,a[i].c,);
printf("%d",ans);
return ;
}

莫名其妙丢20分

正解:

1(by myl)

考虑跳楼的集合

一定会有∑Ci

按照高度排序

高度差的代价==h5-h1

枚举最矮的楼,最高的楼

按照C排序,一个一个的选

总花费Hj-Hi+Ci+Cj+∑选出来的Ci<=T的最大值

复杂度:$O(N^3logN)$

2(by zhx)

dp

按照从低向高排序

$f[i][j]$表示停留在i,已经跳了j栋楼,的最小花费

枚举下一次跳哪栋楼

$f[k][i+1]=min(  f[k][j+1],f[i][j]+C[k]+abs(hk-hi)  )$

复杂度:$O(n^3)$

统计答案的时候枚举i,j观察是否<=T

 #include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include<cstring> using namespace std; int f[][]; struct rec
{
int d,t;
rec(){}
rec(int a,int b)
{
d=a;t=b;
}
bool operator<(const rec &a)const
{
return t<a.t;
}
}z[]; class GUMIAndSongsDiv1 {
public:
int maxSongs(vector <int> duration, vector <int> tone, int T) {
int n=duration.size();
for (int a=;a<n;a++)
z[a]=rec(duration[a],tone[a]);
sort(z,z+n);
memset(f,0x3f,sizeof(f));
f[][]=;
f[][]=z[].d;
for (int a=;a<n;a++)
for (int b=;b<=a+;b++)
if (!b) f[a][b]=;
else
{
for (int c=;c<a;c++)
f[a][b]=min(f[a][b],f[c][b-]+z[a].d+(b== ? : z[a].t-z[c].t));
}
int ans=;
for (int a=;a<n;a++)
for (int b=;b<=n;b++)
if (f[a][b]<=T) ans=max(ans,b);
return ans; }
}; //<%:testing-code%>
//Powered by KawigiEdit 2.1.4 (beta) modified by pivanof!
// BEGIN KAWIGIEDIT TESTING
// Generated by KawigiEdit 2.1.4 (beta) modified by pivanof
bool KawigiEdit_RunTest(int testNum, vector <int> p0, vector <int> p1, int p2, bool hasAnswer, int p3) {
cout << "Test " << testNum << ": [" << "{";
for (int i = ; int(p0.size()) > i; ++i) {
if (i > ) {
cout << ",";
}
cout << p0[i];
}
cout << "}" << "," << "{";
for (int i = ; int(p1.size()) > i; ++i) {
if (i > ) {
cout << ",";
}
cout << p1[i];
}
cout << "}" << "," << p2;
cout << "]" << endl;
GUMIAndSongsDiv1 *obj;
int answer;
obj = new GUMIAndSongsDiv1();
clock_t startTime = clock();
answer = obj->maxSongs(p0, p1, p2);
clock_t endTime = clock();
delete obj;
bool res;
res = true;
cout << "Time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " seconds" << endl;
if (hasAnswer) {
cout << "Desired answer:" << endl;
cout << "\t" << p3 << endl;
}
cout << "Your answer:" << endl;
cout << "\t" << answer << endl;
if (hasAnswer) {
res = answer == p3;
}
if (!res) {
cout << "DOESN'T MATCH!!!!" << endl;
} else if (double(endTime - startTime) / CLOCKS_PER_SEC >= ) {
cout << "FAIL the timeout" << endl;
res = false;
} else if (hasAnswer) {
cout << "Match :-)" << endl;
} else {
cout << "OK, but is it right?" << endl;
}
cout << "" << endl;
return res;
}
int main() {
freopen("meet.in","r",stdin);
freopen("meet.out","w",stdout); vector<int> duration;
vector<int> tone;
int n,T;
scanf("%d",&n);
for (int a=;a<=n;a++)
{
int v;
scanf("%d",&v);
duration.push_back(v);
}
for (int a=;a<=n;a++)
{
int v;
scanf("%d",&v);
tone.push_back(v);
}
scanf("%d",&T);
GUMIAndSongsDiv1 *obj;
int answer;
obj = new GUMIAndSongsDiv1();
answer = obj->maxSongs(duration, tone, T);
printf("%d\n",answer);
/*bool all_right;
all_right = true; vector <int> p0;
vector <int> p1;
int p2;
int p3; {
// ----- test 0 -----
int t0[] = {3,5,4,11};
p0.assign(t0, t0 + sizeof(t0) / sizeof(t0[0]));
int t1[] = {2,1,3,1};
p1.assign(t1, t1 + sizeof(t1) / sizeof(t1[0]));
p2 = 17;
p3 = 3;
all_right = KawigiEdit_RunTest(0, p0, p1, p2, true, p3) && all_right;
// ------------------
} {
// ----- test 1 -----
int t0[] = {100,200,300};
p0.assign(t0, t0 + sizeof(t0) / sizeof(t0[0]));
int t1[] = {1,2,3};
p1.assign(t1, t1 + sizeof(t1) / sizeof(t1[0]));
p2 = 99;
p3 = 0;
all_right = KawigiEdit_RunTest(1, p0, p1, p2, true, p3) && all_right;
// ------------------
} {
// ----- test 2 -----
int t0[] = {1,2,3,4};
p0.assign(t0, t0 + sizeof(t0) / sizeof(t0[0]));
int t1[] = {1,1,1,1};
p1.assign(t1, t1 + sizeof(t1) / sizeof(t1[0]));
p2 = 100;
p3 = 4;
all_right = KawigiEdit_RunTest(2, p0, p1, p2, true, p3) && all_right;
// ------------------
} {
// ----- test 3 -----
int t0[] = {9,11,13,17};
p0.assign(t0, t0 + sizeof(t0) / sizeof(t0[0]));
int t1[] = {2,1,3,4};
p1.assign(t1, t1 + sizeof(t1) / sizeof(t1[0]));
p2 = 20;
p3 = 1;
all_right = KawigiEdit_RunTest(3, p0, p1, p2, true, p3) && all_right;
// ------------------
} {
// ----- test 4 -----
int t0[] = {87,21,20,73,97,57,12,80,86,97,98,85,41,12,89,15,41,17,68,37,21,1,9,65,4,67,38,91,46,82,7,98,21,70,99,41,21,65,11,1,8,12,77,62,52,69,56,33,98,97};
p0.assign(t0, t0 + sizeof(t0) / sizeof(t0[0]));
int t1[] = {88,27,89,2,96,32,4,93,89,50,58,70,15,48,31,2,27,20,31,3,23,86,69,12,59,61,85,67,77,34,29,3,75,42,50,37,56,45,51,68,89,17,4,47,9,14,29,59,43,3};
p1.assign(t1, t1 + sizeof(t1) / sizeof(t1[0]));
p2 = 212;
p3 = 12;
all_right = KawigiEdit_RunTest(4, p0, p1, p2, true, p3) && all_right;
// ------------------
} if (all_right) {
cout << "You're a stud (at least on the example cases)!" << endl;
} else {
cout << "Some of the test cases had errors." << endl;
}
return 0;*/
}
// END KAWIGIEDIT TESTING

鬼畜的正解

T2都市

题目描述

你是能看到第二题的 friends呢。

—— laekov

塔立于都市, 攀登上塔,能够到达更远的地方。但是需要破解谜 题。仍然有 ?个数,但并不给你 而是了?×?−12个数,代表它们两的 和。那么,这 ?个数是多少呢?

输入输出格式

输入格式:

一行个整数 ?。

接下来一行 ?×?−12个数,代表两之和。

输出格式:

第一行个整数 ?代表解的个数 。

接下来 ?行 ,每行 ,每?个数代表一组解,从小到大排列。的顺序 按照字典个数代表一组解,从小到大排列。的顺序 按照字典个数代表一组解,从小到大排列。的顺序 按照字典从大到小排列。

输入输出样例

输入样例#1: 复制

4
3 5 4 7 6 5
输出样例#1: 复制

1
1 2 3 4
输入样例#2: 复制

4
11 17 21 12 20 15
输出样例#2: 复制

2
4 7 8 13
3 8 9 12
P104 zhx 都市
第 5 页 共 6 页

说明

对于 30%的数据, 1≤?≤5,?个数均不超过 10。

对于 60%的数据, 1≤?≤50,?个数均不超过 100。

对于 100%的数据, 1≤?≤300,?个数均不超过 108。

不会做,

最后没时间了,连暴力都没打。

正解

先对给出以及枚举的数的数进行排序

设枚举的数为$a_1,a_2$

给出的数为$b_1,b_2$

性质:

a1+a2==b1

a1+a3==b2

设a2+a3=x

枚举a2+a3等于b里面的哪个数

对于所有的ai,都进行这个操作

每次解除a1,a2,a3

时间复杂度:$O(n^4)≈O(n^3)$

 v#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm> using namespace std; const int maxn=; int n,m,res[maxn],ans[maxn][maxn],z[maxn*maxn],cnt; bool use[maxn*maxn]; void check(int p)
{
memset(use,false,sizeof(use));
if ((z[]+z[]+z[p])&) return;
res[]=(z[]+z[]+z[p])/-z[p];
res[]=z[]-res[];
res[]=z[]-res[];
use[]=use[]=use[p]=true;
for (int a=,b=;a<=n;a++)
{
while (b<=m && use[b])
b++;
if (b>m) return;
res[a]=z[b]-res[];
use[b]=true;
for (int c=;c<a;c++)
{
if (res[c]>res[a]) return;
int v=res[c]+res[a];
int p=lower_bound(z+,z+m+,v)-z;
if (z[p]!=v) return;
int px=p;
while (px && z[px]==z[p])
px--;
px++;
while (px<=m && z[px]==z[p] && use[px])
px++;
if (z[px]!=z[p] || use[px]) return;
p=px;
use[p]=true;
}
}
cnt++;
for (int a=;a<=n;a++)
ans[cnt][a]=res[a];
} int main()
{
freopen("city.in","r",stdin);
freopen("city.out","w",stdout); scanf("%d",&n);
m=n*(n-)/;
for (int a=;a<=m;a++)
scanf("%d",&z[a]);
sort(z+,z+m+);
for (int a=;a<=m;)
{
check(a);
int b=a;
while (b<=m && z[b]==z[a])
b++;
a=b;
}
printf("%d\n",cnt);
for (int a=;a<=cnt;a++)
for (int b=;b<=n;b++)
{
printf("%d",ans[a][b]);
if (b==n) printf("\n");
else printf(" ");
} return ;
}

T3街灯

题目描述

你是能看到第三题的 friends呢。

—— aoao

街上的灯亮起,指引向着远方路 街上的灯亮起,指引向着远方路 街上的灯亮起,指引向着远方路 街上的灯亮起,指引向着远方路 街上的灯亮起,指引向着远方路 。每个街灯上都有一数, 每个街灯上都有一数, 每个街灯上都有一数, 每个街灯上都有一数, 每次询问, 每次询问, 第?个街灯到第 ?个街灯上的数模 ?等于 ?的有几个。

输入输出格式

输入格式:

第一行两个数 ?,?,代表街灯的个数 和询问。

接下来一行 ?个数,代表 街灯上的数。

接下来 ?行,每四个数 ?,?,?,?代表一组询问。

输出格式:

对于每次询问,输出一行代表答案 。

输入输出样例

输入样例#1: 复制

5 2
1 5 2 3 7
1
3 2 2 5 3 0
输出样例#1: 复制

2
1

说明

对于 30%的数据, 1≤?,?≤103。

对于另外 30%的 数据,每次询问?一样。

对于 100%的数据, 1≤?,?≤105,街灯上的数不超过 104,1≤?≤109。

30分是暴力

另外30分可以用莫队水。。

但是标程是用链表做的

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
const int MAXN=1e6;
const int INF=0x7ffff;
inline int read()
{
char c=getchar();int flag=,x=;
while(c<''||c>'') {if(c=='-') flag=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-,c=getchar();return x*flag;
}
int n,m;
int a[MAXN];
struct node
{
int l,r,p,v,id;
}q[MAXN];
int out[MAXN];
int flag=;//p是否都相等
int ansout=;
int mod=;
int base[MAXN];
//map<int,int>happen;
int happen[*MAXN*+];
int comp(const node &a,const node &b)
{
if(base[a.l]==base[b.l])
return base[a.r]<base[b.r];
else return base[a.l]<base[b.l];
}
inline void dele(int pos)
{
happen[a[pos]%mod]--;
}
inline void add(int pos)
{
happen[a[pos]%mod]++;
}
inline void modui()
{
int ll=,rr=-;
int now=;
for(int i=;i<=m;i++)
{
while(ll<q[i].l) dele(ll),ll++;
while(ll>q[i].l) add(ll-),ll--;
while(rr<q[i].r) add(rr+),rr++;
while(rr>q[i].r) dele(rr),rr--;
out[q[i].id]=happen[q[i].v];
}
for(int i=;i<=m;i++)
printf("%d\n",out[i]);
}
int main()
{
// freopen("light.in","r",stdin);
// freopen("light.out","w",stdout);
n=read(),m=read();
int p=sqrt(n);
for(int i=;i<=n;i++) base[i]=(i-)/p;
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<=m;i++)
{
q[i].l=read();
q[i].r=read();
q[i].p=read();
q[i].v=read();
q[i].id=i;
if(i>=&&q[i].p!=q[i-].p) flag=;
}
if(flag&&n>=1e3&&m>=1e3)
{
sort(q+,q+m+,comp);
mod=q[].p;
static map<int,int>happen;
modui();
return ;
}
for(int i=;i<=m;i++)
{
int ans=;
for(int j=q[i].l;j<=q[i].r;j++)
if(a[j]%q[i].p==q[i].v)
ans++;
printf("%d\n",ans);
}
return ;
}

莫队

30分

暴力

60

把%p的余数扔到vector||链表||某个数据结构中

每次二分出l的位置和r的位置

空间复杂度:$O(N)$

100

对p分块

p<=100对于每一个询问预处理

p>100

考虑a[i]%p==v

的值为v+p.v+kp。。

枚举k,k<=100

 #include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int maxn = ;
const int maxv = ;
const int bsz = ;
const int maxb = ; int n, m;
int a[maxn], vb[maxb][maxb], ve[maxb][maxb];
int xb[maxn], xe[maxn];
int i_buf[maxn * maxb * ], tib; void pre() {
memset(ve, , sizeof(ve));
memset(xe, , sizeof(xe));
for (int i = ; i <= n; ++ i)
++ xe[a[i]];
for (int i = ; i <= maxv; ++ i) {
xb[i] = tib;
tib += xe[i];
xe[i] = xb[i];
}
for (int i = ; i <= n; ++ i)
i_buf[xe[a[i]] ++] = i;
for (int m = ; m <= bsz; ++ m) {
for (int i = ; i <= n; ++ i)
++ ve[m][a[i] % m];
for (int i = ; i < m; ++ i) {
vb[m][i] = tib;
tib += ve[m][i];
ve[m][i] = vb[m][i];
}
for (int i = ; i <= n; ++ i)
i_buf[ve[m][a[i] % m] ++] = i;
}
} int queryb(int l0, int r0, int p, int k) {
if (vb[p][k] == ve[p][k])
return ;
int *x1 = lower_bound(i_buf + vb[p][k], i_buf + ve[p][k], l0);
int *x2 = upper_bound(i_buf + vb[p][k], i_buf + ve[p][k], r0);
return x2 - x1;
} int querys(int v, int l0, int r0) {
if (xb[v] == xe[v])
return ;
int *x1 = lower_bound(i_buf + xb[v], i_buf + xe[v], l0);
int *x2 = upper_bound(i_buf + xb[v], i_buf + xe[v], r0);
return x2 - x1;
} int querya(int l0, int r0, int p, int k) {
int ans = ;
for (int i = k; i <= maxv; i += p)
ans += querys(i, l0, r0);
return ans;
} int main() {
freopen("light.in", "r", stdin);
freopen("light.out", "w", stdout); scanf("%d%d", &n, &m);
tib = ;
for (int i = ; i <= n; ++ i)
scanf("%d", a + i);
pre();
while (m --) {
int l, r, p, k;
scanf("%d%d%d%d", &l, &r, &p, &k);
if (p <= bsz)
printf("%d\n", queryb(l, r, p, k));
else
printf("%d\n", querya(l, r, p, k));
}
}

正解

最新文章

  1. z-index--记录七
  2. KVC&amp;&amp;&amp;KVO
  3. Javascript 数组常用操作方法
  4. python之路-Day5
  5. tr
  6. exe4j中&quot;this executable was created with an evaluation错误解决方法
  7. Radeon HD 7850 vs Radeon R9 270X
  8. 阿里云数据库实例的一个db被开发人员删除了 如何恢复
  9. android 内存溢出问题分析
  10. 1.4.2 solr字段类型--(1.4.2.1)字段类型定义和字段类型属性
  11. Oracle“记录被另一个用户锁住” 无法更新删除的解决办法
  12. JVM学习笔记五:虚拟机类加载机制
  13. 关于LeetCode上链表题目的一些trick
  14. html中title小图标的实现
  15. Python自动化中的鼠标事件
  16. maya权重拷贝一对一,一对多
  17. mysql字符串查找(统计客源)
  18. GuGuFishtion HDU - 6390 (杭电多校7E)
  19. HDFS 概述
  20. jQuery 常用的方法

热门文章

  1. prezi,mfc,toefl,java
  2. 日前加拿大平板厂商 Datawind和印度运营商Reliance Communications日前宣布合作
  3. ACM-ICPC 2016 Qingdao Preliminary Contest
  4. 一篇文章教会你理解Scrapy网络爬虫框架的工作原理和数据采集过程
  5. js字符串排序方法
  6. perl JSON模块使用
  7. Project Euler:Problem 58 Spiral primes
  8. 两天学会DirectX 3D之入门
  9. [Java开发之路](6)File类的使用
  10. Gym - 100685F Flood BFS