把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

【HHHOJ】ZJOI2019模拟赛(十二)03.03 解题报告

点此进入比赛

得分: \(0+77+20=97\)

排名: \(Rank\ 5\)

\(Rating\)\(+46\)

\(T1\):【HHHOJ178】依神(点此看题面

这套题目中的唯一一道传统题。

比赛时连暴力都不会写,赛后也不会订正。。。

\(T2\):【HHHOJ179】紫苑(点此看题面

一道提答题,原题详见此题:【UOJ83】【UR #7】水题出题人

这里仅给出造数据程序以及答案:

\(Subtask1\)

手造即可。

\(Subtask2\)

#include<bits/stdc++.h>
#define N 1990//数的总数
#define M 1469//混进数的位置
using namespace std;
int main()
{
    freopen("Shion2.out","w",stdout);
    register int i;cout<<N<<endl;
    for(i=1;i^M;++i) cout<<19<<endl;//输出19(19是我的幸运数字)
    cout<<24<<endl;//混进一个24
    for(i=1;i<=N-M;++i) cout<<19<<endl;//接着输出19
    return 0;
}

\(Subtask3\)

#include<bits/stdc++.h>
#define N 1984
using namespace std;
int p[N+5],ans[N+5];
void DivideAndSolve(int l,int r,int v)//模拟快排来求答案
{
    int x=l+r>>1,i=l,j=x;!ans[p[x]]&&(ans[p[x]]=++v);//使中间的数最小
    p[i]^=p[j]^=p[i]^=p[j],++i<r&&(DivideAndSolve(i,r,v),0);//交换最左边的数和中间的数
}
int main()
{
    freopen("Shion3.out","w",stdout);
    register int i;cout<<N<<endl;for(i=1;i<=N;++i) p[i]=i;//初始化每个位置上是原序列中的第i个数(因为之后会换位置)
    for(DivideAndSolve(1,N,0),i=1;i<=N;++i) cout<<ans[i]<<endl;//递归,然后输出答案
    return 0;
}

\(Subtask4\)

#include<bits/stdc++.h>
#define N 1012//数的总数
#define M 30//序列中数的最大值
using namespace std;
int main()
{
    freopen("Shion4.out","w",stdout);
    register int i,j;cout<<N<<endl;
    for(i=M;i;--i) for(j=1;j<=N/M;++j) cout<<i<<endl;//递减输出每个数,且每个数重复多次
    for(j=1;j<=N-(N/M)*M;++j) cout<<0<<endl;//由于不能恰好除尽,因此剩余的个数我们输出0
    return 0;
}

\(Subtask5\)

#include<bits/stdc++.h>
#define N 1004
using namespace std;
int ans[N+5];
void DivideAndSolve(int l,int r,int v)//二分构造序列
{
    if(l>r) return;//当左边界大于右边界时,退出
    int mid=l+r>>1;ans[mid]=v,//给中间的数赋值
    DivideAndSolve(l,mid-1,v+r-mid+1),//处理左边
    DivideAndSolve(mid+1,r,v+1);//处理右边
}
int main()
{
    freopen("Shion5.out","w",stdout);
    register int i;cout<<N<<endl;
    for(DivideAndSolve(1,N,0),i=1;i<=N;++i) cout<<ans[i]<<endl;//构造,然后输出
    return 0;
}

\(Subtask6\)

#include<bits/stdc++.h>
#define N 4096
#define uint unsigned int
#define swap(x,y) (x^=y^=x^=y)
using namespace std;
int a[N+5];
int main()
{
    freopen("Shion6.out","w",stdout); 
    register int i;register uint seed;
    for(i=1;i<=N;++i) a[i]=i;for(i=N;i;--i) swap(a[i],a[(i+2048)%N+1]);//倒序处理,构造出原数列
    for(i=1;i<=N;++i) a[i]>a[N]&&(a[i]+=1000000);//将已经构造出的序列中大于a[n]的数全部加上一个很大的数,这样就能使得相对大小不变
    for(seed=2166136261,i=1;i^N;++i) seed=(seed*16777619)^a[i];//求出前n-1个数使seed得到的值
    for(i=4092;i<=1004093;++i) if(((seed*16777619)^i)%N==2048) {a[N]=i;break;}//枚举一个合适的a[n]使得seed能够恰好等于2048
    for(cout<<N<<endl,i=1;i<=N;++i) cout<<a[i]<<endl;//输出答案
    return 0;
}

答案

点击下载答案

\(T3\):【HHHOJ180】今宵是飘逸的利己主义者(点此看题面

一道通信题,比赛时只会写暴力,连\(0\le k<1024\)的良心部分分都忘写了。

这题是一道神仙哈希题,尚未订正完。

posted @ 2019-03-06 15:02  TheLostWeak  阅读(232)  评论(0编辑  收藏  举报