9.23——清北模拟赛

T 1 . 回形遍历( ( calc .cpp/c/pas)

时间限制:1 1s s
内存 限制: 256MB
【问题 描 述】
给出一个 n*m 的棋盘,按如下方式遍历,请问(x,y)往后 z 步走到的是哪个格子。

【输入】
输入文件名为 calc.in。
一行,包含五个整数:n,m,x,y,z
【输出】
输出文件名为 calc.out。
输出一行,包含两个整数,表示所在格子的横纵坐标
【输入输出样例】
calc .in        calc .out
4 5 3 0 5     2 4
【 样例解释 】

【数据说明】
对于 70%的数据,1<=n,m,z<=1000,0<=x<n,0<=y<m
对于 100%的数据,1<=n,m,z<=100000,0<=x<n,0<=y<m

 1 #include <cstdio>
 2
 3 #define min(a,b) (a<b?a:b)
 4 inline void read(int &x)
 5 {
 6     x=0; register char ch=getchar();
 7     for(; ch>‘9‘||ch<‘0‘; ) ch=getchar();
 8     for(; ch>=‘0‘&&ch<=‘9‘; ch=getchar()) x=x*10+ch-‘0‘;
 9 }
10 const int N(1000+5);
11 int m,n,y,x,z,tot,cnt[N][N];
12 struct Pos {
13     int x,y;
14     Pos() { x=0, y=0; }
15 }pos[N*N];
16
17 int Presist()
18 {
19     freopen("calc.txt","r",stdin);
20     freopen("calc.out","w",stdout);
21     read(m),read(n);
22     tot=cnt[x=0][y=0]=1;
23     int total=n*m;
24     for(; tot<total; )
25     {
26         for(; tot<total&&!cnt[x][y+1]&&y+1<m; )
27         {
28             cnt[x][++y]=++tot;
29             pos[tot].x=x;
30             pos[tot].y=y;
31         }
32         for(; tot<total&&!cnt[x+1][y]&&x+1<n; )
33         {
34             cnt[++x][y]=++tot;
35             pos[tot].x=x;
36             pos[tot].y=y;
37         }
38         for(; tot<total&&!cnt[x][y-1]&&y-1>=0; )
39         {
40             cnt[x][--y]=++tot;
41             pos[tot].x=x;
42             pos[tot].y=y;
43         }
44         for(; tot<total&&!cnt[x-1][y]&&x-1>=0; )
45         {
46             cnt[--x][y]=++tot;
47             pos[tot].x=x;
48             pos[tot].y=y;
49         }
50     }
51     read(y),read(x),read(z); z+=cnt[x][y];
52     printf("%d %d\n",pos[z].y,pos[z].x);
53     return 0;
54 }
55
56 int Aptal=Presist();
57 int main(int argc,char*argv[]){;}

绕着圈一直转,70分暴力

T2 2 . 排列( ( sum .cpp/c/pas)

时间限制:1 1s s
内存 限制: 256MB
【问题 描 述】
给出一个随机的排列, 请你计算最大值减最小值的差小于等于 0~n-1 的区间分别有多少
个。
【输入】
TYVJ.CN
输入文件名为 sum.in。
第一行一个数 T(<=10),表示数据组数
对于每一组数据:
第一行一个数 n(1<=n<=100,000)
第二行 n 个数 a1...an,表示一个随机的排列
【输出】
输出文件名为 sum.out。
对于每组数据输出 n 行,分别表示差值小于等于 0~n-1 的区间个数
【输入输出样例】
sum .in sum .out
1
4
3 2 4 1
4
5
7
10
【数据说明】
对于 30%的数据,1<=n<=300;
对于 60%的数据,1<=n<=5000
对于 100%的数据,1<=n<=100000

 1 #include <cstring>
 2 #include <cstdio>
 3
 4 #define max(a,b) (a>b?a:b)
 5 #define min(a,b) (a<b?a:b)
 6 inline void read(int &x)
 7 {
 8     x=0; register char ch=getchar();
 9     for(; ch>‘9‘||ch<‘0‘; ) ch=getchar();
10     for(; ch>=‘0‘&&ch<=‘9‘; ch=getchar()) x=x*10+ch-‘0‘;
11 }
12 const int N(100005);
13 int n,num[N],ans[10000005];
14
15 int Presist()
16 {
17     freopen("sum.in","r",stdin);
18     freopen("sum.out","w",stdout);
19     int t; read(t);
20     for(int max_,min_; t--; )
21     {
22         read(n); memset(ans,0,sizeof(ans));
23         for(int i=1; i<=n; ++i) read(num[i]);
24         for(int l=1; l<=n; ++l)
25         {
26             max_=min_=num[l];
27             for(int r=l; r<=n; ++r)
28             {
29                 max_=max(max_,num[r]);
30                 min_=min(min_,num[r]);
31                 ans[max_-min_]++;
32             }
33         }
34         for(int i=0; i<n; ++i)
35             printf("%d\n",ans[i]),ans[i+1]+=ans[i];
36     }
37     return 0;
38 }
39
40 int Aptal=Presist();
41 int main(int argc,char*argv[]){;}

60分暴力:n^2枚举,枚举左端点,向右更新区间最值。

3. 近似 排列计数( count .cpp/c/pas)


时间限制:1 1s s
内存 限制: 256MB
【问题 描 述】
对于一个 1~n 的排列,如果满足第 i 个数|a i -i|<=k,则称该排列为 K-近似排列。
现在排列的若干位置已经确定, 你需要计算剩下的数有多少种排列方法使得形成的排列
是 K-近似排列。
【输入】
输入文件名为 count.in。
第一行一个数 T(<=10),表示数据组数
对于每一组数据:
第一行三个数 n,m,k,分别表示排列长度、已确定位置的个数和近似参数 K
接下来 m 行,每行两个数 x、y,表示已经确定第 x 个数是 y
【输出】
TYVJ.CN
输出文件名为 count.out。
对于每组数据输出一行,包含一个数,表示方法个数(对 1,000,000,007 取模)
【输入输出样例】
count .in count .out
1
4 1 1
2 3
2
【数据说明】
对于 30%的数据,1<=n,m<=10,k<=2
对于 50%的数据,1<=n,m<=20,k<=2
对于 70%的数据,1<=n<=100000,m<=100,k<=2
对于 100%的数据,1<=n<=10^9,m<=100,k<=2

 1 #include <algorithm>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <cstdio>
 5
 6 const int mod(1000000007);
 7 inline void read(int &x)
 8 {
 9     x=0; register char ch=getchar();
10     for(; ch>‘9‘||ch<‘0‘; ) ch=getchar();
11     for(; ch>=‘0‘&&ch<=‘9‘; ch=getchar()) x=x*10+ch-‘0‘;
12 }
13 const int N(100005);
14 int n,m,k,num[N],ans,jc,cnt;
15 int x[111],y[111],must[111];
16
17 inline bool judge()
18 {
19     for(int i=1; i<=n; ++i)
20         if(abs(num[i]-i)>k) return 0;
21     return true;
22 }
23
24 int Presist()
25 {
26     freopen("count.in","r",stdin);
27     freopen("count.out","w",stdout);
28     int t; read(t);
29     for(; t--; ans=0)
30     {
31          read(n),read(m),read(k);jc=1;
32          for(int i=1; i<=n; ++i) jc*=i;
33          for(int i=1; i<=m; ++i)
34          {
35              read(x[i]),read(y[i]),must[x[i]]=y[i];
36              if(abs(x[i]-y[i])>k) goto Love;
37          }
38          for(int i=1; i<=n; ++i) num[i]=i;
39          do {
40              for(int i=1; i<=m; ++i)
41                  if(num[x[i]]!=must[x[i]]) goto Pos;
42              if(judge()) ans++,ans%=mod; Pos:;
43          }while(std::next_permutation(num+1,num+n+1));
44 Love     :printf("%d\n",ans);
45     }
46     return 0;
47 }
48
49 int Aptal=Presist();
50 int main(int argc,char*argv[]){;}

爆零暴力、、全排列挨着判

时间: 2024-08-05 11:28:55

9.23——清北模拟赛的相关文章

2017.9.23清北第二场

1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 const int MAXN=400001; 8 inline void read(int &n) 9 { 10 char c=getchar();n=0;bool flag=0; 11 while

2017-10-29-morning-清北模拟赛

T1 遭遇 1 #include <algorithm> 2 #include <cstdio> 3 #include <cmath> 4 5 inline void read(int &x) 6 { 7 x=0; register char ch=getchar(); 8 for(; ch>'9'||ch<'0'; ) ch=getchar(); 9 for(; ch>='0'&&ch<='9'; ch=getchar(

2017-10-28-morning-清北模拟赛

T1 立方数(cubic) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK定义了一个数叫“立方数”,若一个数可以被写作是一个正整数的3次方,则这个数就是立方数,例如1,8,27就是最小的3个立方数. 现在给定一个数P,LYK想要知道这个数是不是立方数. 当然你有可能随机输出一些莫名其妙的东西来骗分,因此LYK有T次询问~ 输入格式(cubic.in) 第一行一个数T,表示有T组数据. 接下来T行,每行一个数P. 输出格式(cubic.out) 输出

2018.2.23 省选模拟赛

从这里开始 Problem A cycle Problem B meal Problem C naive Problem A cycle 判断是否有经过一个点的负环,我们可以跑最短路.判断这个点到自己的最短路是否是负数. 于是可以二分环大小跑dfs版spfa. 于是可以分层图做时间复杂度四方的dp. (YYR给的数据水得吓人,这两个做法居然都跑过了.然后都被我和jmr卡掉了) 注意到如果一个点走不超过$k$条边回到自己的最短路的长度是负数,那么走不超过$k + 1$条边也是. 因此我们可以二分答

清北模拟题4

更正:第三组:不存在相同的字符|str|=26,26<=n<=100 题解:kmp+矩阵乘法(类似 GT算法,只需将 GT算法的代码(ps:GT算法是一道题)进行一下修改). #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define MAXN 10100 #define MAXM 110 #define M 1000000007 using

清北模拟 求和

给定项数.公比.模数,求首项为1的等比数列的和 #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<cmath> #define ll long long using namespace std; ll n,k,p; ll sum,numa,n

模拟赛题目选集

A. [线上训练13]二叉树 题解:贪心,先求出这两个序列,i在第一个序列位置为\(a[i]\),第二个为\(b[i]\),如果\(a[i] > b[i]\), \(ans += 2^{a[i]-b[i]}\) #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<set> #inclu

2.23模拟赛

浪了一发普及模拟赛 题面见此 [样例输入] 4 1 1 2 1 1 1 [样例输出] 20 [数据规模和范围] 对于 30%的数据,n≤1000. 对于另外 30%的数据,bi=1. 对于 100%的数据,n≤1 000 000,bi≤1000. sol:单边记贡献,(x,y)边的贡献就是 Size[y]*(n-Size[y])*Dis[x][y],因为父亲都小于当前点,直接倒着跑一遍记Size就可以了,如果无序的话可以用拓扑 #include <bits/stdc++.h> using na

【BZOJ】【2741】【FOTILE模拟赛】L

可持久化Trie+分块 神题……Orz zyf & lyd 首先我们先将整个序列搞个前缀异或和,那么某一段的异或和,就变成了两个数的异或和,所以我们就将询问[某个区间中最大的区间异或和]改变成[某个区间中 max(两个数的异或和)] 要是我们能将所有[l,r]的答案都预处理出来,那么我们就可以O(1)回答了:然而我们并不能. 一个常见的折中方案:分块! 这里先假设我们实现了一个神奇的函数ask(l,r,x),可以帮我们求出[l,r]这个区间中的数,与x最大的异或值. 我们不预处理所有的左端点,我