noip模拟题11.16 距noip2016还剩两天
2016-11-16 20:01
274 查看
T1 LGTB 与序列
LGTB 得到了一个序列,他想在这个序列中选择一个最长的连续子序列,使得这个子序列的最大公约数等于1。请告诉他他能得到的最大长度,如果没有这样的序列,输出-1输入
输入第一行包含一个整数n 代表序列大小接下来一行,包含n 个整数a1, a2, …, an,代表序列
对于50% 的数据,1<n<1000
对于100% 的数据,1<n<10^5, 1<ai<10^9
输出
输出包含一个整数l,代表最长的连续子序列,如果无解请输出-1。样例
样例输入12
7 2
样例输出1
2
样例输入2
3
2 2 4
样例输出2
-1
这题乍一看很恼火,考试时花了点时间找一串序列需要剔除某些数的情况,但我找不到…然后又花了点时间打了个素数表…然后…惊奇地发现…这题太坑了,只要找整个序列的gcd,如果gcd==1,就输出 n,否则输出-1。因为一个序列不满足的话肯定所有数都有一个公约数,所以只要两两求gcd就行…
代码:
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; long long que[100005]; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline long long gcd(long long a,long long b) { if(b==0)return a; else return gcd(b,a%b); } int main() { freopen("seq.in","r",stdin); freopen("seq.out","w",stdout); int n=read(); for(int i=1;i<=n;++i) que[i]=read(); if(n==1) { if(que[1]==1) printf("1"); else printf("-1"); return 0; } long long tmp=que[1]; for(int i=2;i<=n;i++) { tmp=gcd(tmp,que[i]); if(tmp==1) { printf("%d",n); return 0; } } printf("-1"); return 0; }
T2 LGTB 与桌子
LGTB 新买了一张n m 的矩(桌) 阵(子),他想给某些1 1 的小矩形染色,使得染色之后,原矩阵的每个n×n 的子矩阵中都包含恰好k 个被染色了的小矩形。他想知道有多少种染色方案能让他满足上述要求
因为答案可能很大,请输出方案数模1000000007 (109 + 7) 后的值
输入
输入第一行包含三个整数n, m, k 意义如题面所示对于15% 的数据,1<n×m<20, n<m
对于40% 的数据,1<n<10, n<m<1000
对于100% 的数据,1<n<100, n<m<10^18, 0<k<n^2
输出
输出包含1 个整数,代表LGTB 的方案数样例
样例输入15 6 1
样例输出1
45
样例说明
样例如图所示,如果在灰色区域染一个格子,有20 种方案。如果在两边的白色格子各染一个格子,有25 种方案。共45 种方案。
表示这种需要找规律的dp题我真的是无能为力…考试时码了个暴力交上去得了20分…
不难得到这个性质:当前n列有k个染色的时候,假设第1列有x个染色,那么第n+1列也应该有x个染色,则kn+i列的染色个数与第i列染色个数相同。
那么我们可以设数组 dp[i][j] 表示一个 i×n 的矩阵中涂 j 个方块的方案数。因为 m 很大,我们可以不必将所有矩阵求出来,dp[i+1][j+k]=∑dp[i][j]×C
[k]^T[i],dp
[k]即为答案。其中T[i]表示m列中共有多少个kn+i列,然后用快速幂预处理C
[p]^T[i]。
C表示组合数,C[i][j] 意为在 i 个数中选 j 个的方案数。由于当前已经推到最后一个方块了,所以前面的方案数为C
[k]^T[i]种。
值得注意的是,我们将n×m的方块弄成n×n的方块排列在一起后,最有一个方块有可能不是n×n的,所以C
[k]^T[i]中的T[i]有可能不一样,那么在快速幂求解的时候,不空缺的部分要求^((m/n)+1),空缺部分要求^(m/n)。
代码:
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #ifdef WIN32 #define AUTO "%I64d" #else #define AUTO "%lld" #endif using namespace std; const int mod=1e9+7; long long dp[105][10005],C[105][105]; long long val[2][105]; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline long long pow(long long tmp,long long k) { if(k==1)return tmp%mod; if((k&1)==1) { long long op=pow(tmp,k>>1)%mod; return (((op*op)%mod)*tmp)%mod; } else { long long op=pow(tmp,k>>1)%mod; return (op*op)%mod; } } int main() { freopen("table.in","r",stdin); freopen("table.out","w",stdout); int n=read();long long m;scanf(AUTO,&m);int k=read(); for(int i=0;i<=n+3;i++) { C[i][0]=C[i][i]=1; for(int j=1;j<i;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod; }//杨辉三角形求组合数 dp[0][0]=1; long long num=m/n;//一共有多少个方块 long long le=m%n;//多出来无法构成n×n方块的序列 for(int i=0;i<=n;i++) { val[0][i]=pow(C [i],num);//0表示有空缺部分 val[1][i]=pow(C [i],num+1);//1表示无空缺部分 } for(int i=0;i<n;i++)//直接处理最后一个也许不完整的方块 for(int j=0;j<=i*n;j++) for(int op=0;op<=n;op++) { long long tmp=i<le?val[1][op]:val[0][op]; //此处是i<le,因为我们是从i推i+1 (dp[i+1][j+op]+=(dp[i][j]*tmp)%mod)%=mod; }//新加一列,在新加一列中涂op个小方块 printf(AUTO,dp [k]); return 0; }
T3 LGTB 与正方形
LGTB 最近迷上了正方形,现在他有n 个在二维平面上的点,请你告诉他在这些点中选4 个点能组成四条边都平行于坐标轴的正方形的方案数有多少输入
输入第一行包含一个整数n,代表点的数量接下来n 行每行包含两个整数xi, yi,代表点的坐标
对于10% 的数据,1<n<50
对于30% 的数据,1<n<1000
对于100% 的数据,1<n<10^5,0<xi, yi<10^5
数据保证没有两点在同一位置
输出
输出包含一个整数代表方案数样例
样例输入15
0 0
0 2
2 0
2 2
1 1
样例输出1
1
样例输入2
9
0 0
1 1
2 2
0 1
1 0
0 2
2 0
1 2
2 1
样例输出2
5
直接暴力肯定是要T的。
考虑优化:用集合储存每个横坐标,再将每个横坐标上的点存下来。接下来有两种暴力方法:
1:枚举每个点,再枚举这个点上面的点(也就是横坐标相同,纵坐标大于这个点的点),判断右边是否有两个点和这两个点的纵坐标相同,且横坐标之差等于纵坐标之差。
2:枚举每个横坐标,再枚举大于这个横坐标的横坐标,从第一个开始向上,如果第一个的纵坐标小了,指针1++,大了同理,若相等,判断两个横坐标上面是否有高度为两个横坐标之差点。
数组存不下,用集合。以上方法可以过60%。
正解:将横坐标分为两组:点数大于400的分为长边,小于400的分为短边,短边用方法1处理,但同时还要判断左边的长边是否有满足的情况。长边用方法2处理。用集合处理过70%,hash处理可以AC,但我不会……(废人)。
70%代码:
#include<set> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct node{ int x,y; bool operator<(const node&a)const { if(a.x!=x)return a.x>x; else return a.y>y; } }gg[100005]; int small[100005],big[100005],low; int high,bb[100005],vis[100005]; set<node>judge; vector<int>ma[100005]; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int main() { freopen("square.in","r",stdin); freopen("square.out","w",stdout); int n=read( b911 ),maxn=0; for(int i=1;i<=n;i++) { gg[i].x=read();gg[i].y=read(); ma[gg[i].x].push_back(gg[i].y); judge.insert(gg[i]); maxn=max(maxn,gg[i].x); vis[gg[i].x]=1; } for(int i=0;i<=maxn;i++) if(vis[i]) { int num=ma[i].size(); if(num<400) small[++low]=i; else { big[++high]=i; bb[i]=1; } sort(ma[i].begin(),ma[i].end()); } int ans=0; for(int i=1;i<=low;i++) for(int j=0;j<ma[small[i]].size();j++) for(int k=j+1;k<ma[small[i]].size();k++) { int tmp=small[i]-(ma[small[i]][k]-ma[small[i]][j]); if(tmp) if(judge.count((node){tmp,ma[small[i]][j]})) if(judge.count((node){tmp,ma[small[i]][k]})) if(bb[tmp]==1) ans++; tmp=small[i]+(ma[small[i]][k]-ma[small[i]][j]); if(tmp<=maxn) if(judge.count((node){tmp,ma[small[i]][j]})) if(judge.count((node){tmp,ma[small[i]][k]})) ans++; } for(int i=1;i<=high;i++) for(int j=i+1;j<=high;j++) { int op1=0,op2=0; while(op1<ma[big[i]].size()&&op2<ma[big[j]].size()) { if(ma[big[i]][op1]>ma[big[j]][op2]) op2++; else if(ma[big[i]][op1]<ma[big[j]][op2]) op1++; else { int tmp=big[j]-big[i]; if(judge.count((node){big[i],ma[big[i]][op1]+tmp})) if(judge.count((node){big[j],ma[big[j]][op2]+tmp})) ans++; op1++;op2++; } } } printf("%d",ans); return 0; }
表示最近的题都很阴阳怪气,临近noip,我真是越做越慌……太吓人了……⊙﹏⊙
相关文章推荐
- 【JZOJ4899】【NOIP2016提高A组集训第17场11.16】雪之国度
- JZOJ4898. 【NOIP2016提高A组集训第17场11.16】人生的价值
- 【JZOJ4898】【NOIP2016提高A组集训第17场11.16】人生的价值
- Cpp环境【CQ-NOIP2016四校联考模拟题(一)P3】树上的询问
- 51nod1743 JZOJ4899【NOIP2016提高A组集训第17场11.16】雪之国度
- noip模拟题11.15 距noip2016还剩三天
- JZOJ4899. 【NOIP2016提高A组集训第17场11.16】雪之国度
- noip模拟题11.17 距noip2016还剩一天
- 【NOIP2016提高A组模拟9.3】总结
- bzoj 4720: [Noip2016]换教室【期望dp】
- C++——NOIP模拟题——病毒
- [NOIp2016] 换教室
- NOIP2016提高组 快速荷叶叶变换
- [NOIP2016] 翻车记
- NOIP2016-DAY1 简单题解?
- noip2016题解
- 【JZOJ4755】【NOIP2016提高A组模拟9.4】快速荷叶叶变换
- NOIP2016普及组比赛总结
- BZOJ4720 [Noip2016]换教室
- [Noip模拟题]RP字符串