73 条题解
-
2不退 LV 8 @ 2018-03-14 23:02:38
并没有理解各位大佬的(优秀)做法,于是打了纯模拟……
相信不需要任何注释就能看懂(因为实在是太朴素了……)
代码有点长,效率也不高,最慢一个450ms,但胜在容易理解……
另外膜一下楼下大佬O(10*K)做法,真的是飞速,虽然我不太懂……#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,k,s,e,cr,now; int a[200005],nc[200005]; int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;++i) a[i]=i; for(int i=1;i<=k;++i) { scanf("%d%d%d",&s,&e,&cr); if(cr<=s-2) { memset(nc,0,sizeof(nc)); now=1; for(int j=s;j<=e;++j) { nc[now]=a[j]; now++; a[j]=0; } for(int j=n;j>=cr+1;--j) a[j+e-s+1]=a[j]; now=1; for(int j=cr+1;j<=cr+1+e-s;++j) { a[j]=nc[now]; now++; } now=1; for(int j=1;j<=n+e-s+1;++j) { if(a[j]!=0) { nc[now]=a[j]; now++; } } memset(a,0,sizeof(a)); for(int j=1;j<=n;++j) a[j]=nc[j]; } if(cr>=s&&cr<e) { memset(nc,0,sizeof(nc)); now=1; for(int j=e+1;j<=e+cr+1-s;++j) { nc[now]=a[j]; now++; a[j]=0; } for(int j=n;j>=s;--j) a[j+cr+1-s]=a[j]; now=1; for(int j=s;j<=cr;++j) { a[j]=nc[now]; now++; } now=1; for(int j=1;j<=n+cr+1-s;++j) { if(a[j]!=0) { nc[now]=a[j]; now++; } } memset(a,0,sizeof(a)); for(int j=1;j<=n;++j) a[j]=nc[j]; } if(cr>=e) { memset(nc,0,sizeof(nc)); now=1; for(int j=e+1;j<=e+cr-s+1;++j) { nc[now]=a[j]; now++; a[j]=0; } for(int j=n;j>=s;--j) a[j+cr-s+1]=a[j]; now=1; for(int j=s;j<=cr;++j) { a[j]=nc[now]; now++; } now=1; for(int j=1;j<=n+cr-s+1;++j) { if(a[j]!=0) { nc[now]=a[j]; now++; } } memset(a,0,sizeof(a)); for(int j=1;j<=n;++j) a[j]=nc[j]; } } for(int i=1;i<=10;++i) cout<<a[i]<<endl; return 0; }
-
22017-05-07 22:23:56@
/* 此题神坑啊,一定要注意剪切粘贴的细节;坑啊坑啊 天啊噜啊 */ #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <iomanip> #include <cstdlib> using namespace std; const int maxn=100000+10; int text[maxn],buffer[maxn]; int n,k; int a,b,c; int main() { cin>>n>>k; for(int i=1;i<=n;i++) text[i]=i; while(k--) { cin>>a>>b>>c; int z=b-a+1; memcpy(buffer,text+a,sizeof(int)*z);//将剪切断落复制出来 memmove(text+a,text+b+1,sizeof(int)*(n-b));//将剪切断落后面的部分给弄到剪切断落位置前面来 n-=z;//长度剪掉,到这里为止完成了将剪切断落剪出来的任务 memmove(text+c+z+1,text+c+1,sizeof(int)*(n-c));//将粘贴位置数字后移 memcpy(text+c+1,buffer,sizeof(int)*z);//将断落粘贴进去 n+=z; } for(int i=1;i<=10;i++) cout<<text[i]<<endl; return 0; }
-
12020-11-17 11:19:09@
看到各种暴力的,突然醒悟,我想个屁的算法啊。。。强烈要求数据再加强十倍。。。
#1 Accepted 1ms 204.0 KiB
#2 Accepted 1ms 228.0 KiB
#3 Accepted 1ms 220.0 KiB
#4 Accepted 8ms 408.0 KiB
#5 Accepted 2ms 336.0 KiB
#6 Accepted 2ms 336.0 KiB
#7 Accepted 2ms 204.0 KiB
#8 Accepted 8ms 444.0 KiB
#9 Accepted 8ms 432.0 KiB
#10 Accepted 3ms 344.0 KiB这题目第一眼给人感觉像是块状链表,因为涉及到块移动与检索,但仔细看了一下,由于题目不需要查询具体结构,只有修改,所以用链表就够了。
由于初始数据是有序的,这意味着我们只需要一个数字的起点,与数字的长度就能表示一长串数据。而当我们需要进行剪切的时候,则是将链表切开,然后将插入点也切开,然后将切出的链表接到接入点就可以了。
需要注意的是,由于剪切的首位位置可能存在于同一个链表结点中,也可能存在于不同链表结点中,而两者切段的操作细节是不同的,所以最好分类讨论。
(本来还想着考虑链表结点的合并,结果提交上去就过了,然后看了一下题解,诶……不说了)
-
12018-10-30 15:48:43@
这道题给的启示就是好好打暴力,虽然理论上是O(nk)但实际上不可能跑到
粘贴文本可分成五步:
1.切下来的部分放进新数组
2.原文本后面的变到前面
3.将要粘的位置后面的部分取出来
4.切下来的部分粘回去
5.要粘位置后的部分放回去
数组下标可能有些混乱,最好开辅助变量记录一下#include<iostream> using namespace std; int x[100010],lin[100010],e[100010]; int main() { int n,k,i,j,a,b,c,na,nb,nc; cin>>n>>k; for(i=1;i<=n;i++) x[i]=i; for(i=1;i<=k;i++) { cin>>a>>b>>c; na=0; nb=0; //五个循环 nc=0; for(j=a;j<=b;j++) //切 { na++; lin[na]=x[j]; } for(j=b+1;j<=n;j++) //前移 x[j-na]=x[j]; for(j=c+1;j<=n-na;j++) //要粘的位置后面 { nc++; e[nc]=x[j]; } for(j=c+1;j<=c+na;j++) //粘回去 x[j]=lin[j-c]; for(j=n-nc+1;j<=n;j++) //放回去 x[j]=e[j-n+nc]; } for(i=1;i<=10;i++) cout<<x[i]<<endl; return 0; }
-
12017-11-05 14:12:06@
#include <stdio.h> int a[1010],b[1010],c[1010]; int N,K; int get(int n,int k){ if (k==0) return n; if (c[k]+1>a[k]){ if ((n<a[k])||(n>(c[k]+1+b[k]-a[k]))) return get(n,k-1); if (n>=c[k]+1) return get(n+a[k]-c[k]-1,k-1); return get(n+b[k]-a[k]+1,k-1); } if (c[k]+1<a[k]){ if ((n<c[k]+1)||(n>b[k])) return get(n,k-1); if (n<=c[k]+1+b[k]-a[k]) return get(n+a[k]-c[k]-1,k-1); return get(n-b[k]+a[k]-1,k-1); } return get(n,k-1); } int main(){ scanf("%d %d",&N,&K); for (int i=1;i<=K;i++) scanf("%d %d %d",&a[i],&b[i],&c[i]); for (int i=1;i<=10;i++) printf("%d\n",get(i,K)); return 0; }
O(10*k)的写法
-
12017-09-03 11:25:30@
用memmove复制就可以了
具体过程见注释
代码如下
#include<iostream> #include<cstdio> #include<map> #include<algorithm> #include<cstring> using namespace std; int n,k,a,b,c; int x[100000],y[100000]; int main(){ scanf("%d%d",&n,&k); for(int i=0;i<n;i++) x[i]=i+1; for(int i=1;i<=k;i++){ scanf("%d%d%d",&a,&b,&c); if(c==a-1) continue;//特判,c==a-1等价于不移 int l=b-a+1; memmove(y,x+a-1,sizeof(int)*l); //把要剪切的东西复制到y上 if(c<a){ memmove(x+l+c,x+c,sizeof(int)*(a-c-1));//前面的往后移 }else{ memmove(x+a-1,x+b,sizeof(int)*(c-a+1));//后面的往前移 } memmove(x+c,y,sizeof(int)*l); //把剪切掉的部分粘贴到正确位置 } for(int i=0;i<=9;i++) printf("%d\n",x[i]); return 0; }
-
02017-07-01 23:16:44@
这题坑出屎了,一开始写了个splay,后来发现是模拟
-
02017-05-27 21:21:47@
Accepted
状态 耗时 内存占用
#1 Accepted 3ms 256.0KiB
#2 Accepted 2ms 384.0KiB
#3 Accepted 3ms 376.0KiB
#4 Accepted 22ms 256.0KiB
#5 Accepted 21ms 384.0KiB
#6 Accepted 43ms 488.0KiB
#7 Accepted 73ms 512.0KiB
#8 Accepted 167ms 640.0KiB
#9 Accepted 163ms 736.0KiB
#10 Accepted 203ms 768.0KiB
代码#include<iostream> using namespace std; int l[100010],n,k,a,b,c,t,n1,n2,n3,n4,n5,n6; int main() { cin>>n>>k; for(int i=1;i<=n+1;i++) l[i-1]=i; for(int i=1;i<=k;i++) { cin>>a>>b>>c; t=0; for(int j=1;j<=a-1;j++) t=l[t]; n3=t; n4=l[n3]; for(int j=a;j<=b;j++) t=l[t]; n5=t; n6=l[n5]; l[n3]=n6; t=0; for(int j=1;j<=c;j++) t=l[t]; n1=t; n2=l[n1]; l[n1]=n4; l[n5]=n2; } t=0; for(int i=1;i<=10;i++) { t=l[t]; cout<<t<<endl; } return 0; }
-
02014-07-09 11:29:15@
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#define N 100001
using namespace std;
int tmp[N],f[N];
long long shark,n,k,a,c,b;
void zzjdmt1()
{
for(int i=1;i<=N;i++) tmp[i]=f[i];
for(int i=1;i<=a-c-1;i++) f[c+shark+i]=tmp[c+i];
for(int i=1;i<=shark;i++) f[c+i]=tmp[a+i-1];
}
void zzjdmt2()
{
for(int i=1;i<=N;i++) tmp[i]=f[i];
for(int i=1;i<=c-a+1;i++) f[a+i-1]=tmp[b+i];
for(int i=1;i<=shark;i++) f[c+i]=tmp[a+i-1];
}
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=k;i++){
cin>>a>>b>>c;
shark=b-a+1;
if(c+shark<a) zzjdmt1();
if(c+1==a) continue;
if(c+1<a && c+shark>=a) zzjdmt1();
if(c>=b) zzjdmt2();
if(c<b && c+1>a) zzjdmt2();
}
for(int i=1;i<=10;i++) cout<<f[i]<<endl;
//system("pause");
return 0;
}做自己的明天吧
-
02014-01-01 11:59:29@
Vijos 题解:http://hi.baidu.com/umule/item/2c997f8ed9600fdae596e017
有疑问请留言 共同进步 -
02013-02-16 10:17:55@
-
02012-10-11 17:21:57@
数组下标即为该数字,存储数据为下一个数字,恰也为下一个数字的下标,更改链结即可。0ms
var
n,k,a,b,c,i,ii,c1,c2,c3,c4:longint;
nex:array[-1..100001] of longint;function pos(x:longint):longint;
var
i,j:longint;
begin
j:=0;
for i:=1 to x do
j:=nex[j];
exit(j);
end;begin
readln(n,k);
for i:=0 to n-1 do nex[i]:=i+1;
nex[n]:=0; nex[-1]:=0;
for i:=1 to k do
begin
readln(a,b,c);
c1:=pos(a-1);
c2:=pos(b);
c4:=nex[c1];
nex[c1]:=nex[c2];
c3:=pos(c);
nex[c2]:=nex[c3];
nex[c3]:=c4;
end;
i:=0;
k:=0;
repeat
writeln(nex[i]);
i:=nex[i];
inc(k);
until k=10;
end. -
02012-08-05 22:08:53@
模拟水过
include # include using namespace std;int n;void paste(int num[],int a,int b,int c){ int result[n*2+1]; int i; for (i=a;i=c+1;i--)num[i]=num; for (i=1;i
-
02012-07-22 10:00:28@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 9ms
├ 测试数据 06:答案正确... 119ms
├ 测试数据 07:答案正确... 103ms
├ 测试数据 08:答案正确... 603ms
├ 测试数据 09:答案正确... 603ms
├ 测试数据 10:答案正确... 478ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:1915ms
TNND 数据需要很大。。。 -
02012-08-02 10:10:41@
点击这里查看
-
02010-07-16 20:14:04@
move!!!!!!!!!!
太神了!!
傻瓜式模拟,不用任何优化~~~~ -
02010-04-13 17:42:36@
没天理啊,两次60分,莫名其妙的255错误,居然是数组开小了?
-
02010-04-04 11:13:17@
谁有c++的题解
-
02009-11-07 11:19:01@
没秒杀,请大牛指点优化……
var
a,b:array[1..100000]of longint;
i,j,k,n,x,y,c:longint;
begin
readln(n,k);
for i:=1 to n do
a[i]:=i;
for i:=1 to k do
begin
readln(x,y,c);
b:=a;
move(b[y+1],b[x],4*(n-y));
move(a[x],a[c+1],4*(y-x+1));
for j:=1 to c do
a[j]:=b[j];
for j:=y-x+c+2 to n do
a[j]:=b[j-y+x-1];
end;
for i:=1 to 10 do writeln(a[i]);
end. -
02009-11-04 11:44:16@
var n,m,a,b,tmp,c,i,j:longint;
e,d:array[1..100000]of longint;
begin
readln(m,n);
for i:=1 to m do d[i]:=i;
for i:=1 to n do begin
read(a,b,c);
tmp:=b-a+1;
for j:=a to b do
e[j-a+1]:=d[j];
for j:=b+1 to m do
d[j-tmp]:=d[j];
for j:=m downto c+1 do
d[j+tmp]:=d[j];
for j:=c+1 to tmp+c do d[j]:=e[j-c];
end;
for i:=1 to 10 do writeln(d[i]);
end.
纯模拟怎么会错???