NOIP2017赛前模拟10月30日总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOIP2017赛前模拟10月30日总结相关的知识,希望对你有一定的参考价值。
题目1:
n个人参赛(n<=100000),每个人有一个权值··已知两个人权值绝对值之差小于等于K时,两个人都有可能赢,若大于则权值大的人赢···比赛为淘汰制,进行n-1轮·问最后可能赢的人有多少个?
考点:简单分析
直接将权值排序,从大到小扫一遍直到num[i+1]-num[i]>k停止··此时答案等于n-i
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<string> #include<cstring> #include<algorithm> using namespace std; const int N=1e5+5; inline int R() { char c;int f=0; for(c=getchar();c<‘0‘||c>‘9‘;c=getchar()); for(;c<=‘9‘&&c>=‘0‘;c=getchar()) f=(f<<3)+(f<<1)+c-‘0‘; return f; } int n,k,T,num[N]; int main() { T=R(); while(T--) { n=R(),k=R(); for(int i=1;i<=n;i++) num[i]=R(); sort(num+1,num+n+1); int ans=1; for(int i=n-1;i>=1;i--) { if(num[i+1]-num[i]<=k) ans++; else break; } cout<<ans<<"\n"; } return 0; }
题目2:
有n个数从左到右排列··豆豆和豆沙从左到右交替取,豆豆第一次可以取1个或2个数,之后若前一个人拿了K个数··则后面的人只能拿K或K+1个数··n<=20000,若每次两人拿的时候都采用最优策略,那么豆豆会比豆沙多拿总和多大的数?
考点:dp
和第一次NOIP总结中的T2很像··我们用f[i][j]表示先手从i开始拿j个之后能最多比后手多拿多大,得出转移方程:
f[i][j]=sum[i+j-1]-sum[i-1]-max(f[i+j][j],f[i+j][j+1]);
sum为数的前缀和,最后比较f[1][1]和f[1][2]即可,由于j每次枚举最大不会超过根号n,复杂度为n^3/2;
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<string> #include<cstring> #include<algorithm> using namespace std; const int N=2e4+5; int T,n,f[N][205],num[N],sum[N]; inline int R(){ char c;int f=0,i=1; for(c=getchar();(c<‘0‘||c>‘9‘)&&c!=‘-‘;c=getchar()); if(c==‘-‘) i=-1,c=getchar(); for(;c<=‘9‘&&c>=‘0‘;c=getchar()) f=(f<<3)+(f<<1)+c-‘0‘; return f*i; } int main() { T=R(); while(T--){ memset(sum,0,sizeof(sum));memset(f,0,sizeof(f)); n=R(); for(int i=1;i<=n;i++) sum[i]=num[i]=R(),sum[i]+=sum[i-1]; for(int i=n;i>=1;i--) for(int j=1;i+j-1<=n&&j<=200&&j<=i+1;j++) f[i][j]=sum[i+j-1]-sum[i-1]-max(f[i+j][j],f[i+j][j+1]); cout<<max(f[1][2],f[1][1])<<endl; } return 0; }
题目3:
给定一个无向图,问图中共边三元环有多少对,点数n<=100000,m<=200000;
考点:图论
很妙的一道题···我们枚举每一个点u··然后找到与该点相连且度数比该点小的点v··然后找既与v相连由于u相连的点的数量计算对答案贡献即可··复杂度为m^3/2次方
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> #include<vector> using namespace std; const int M=2e5+5; const int N=1e5+5; vector<int>ed[N]; inline int R(){ char c;int f=0; for(c=getchar();c<‘0‘||c>‘9‘;c=getchar()); for(;c<=‘9‘&&c>=‘0‘;c=getchar()) f=(f<<3)+(f<<1)+c-‘0‘; return f; } int T,n,m,du[N],tag[N],tim; long long ans=0; inline void pre(){ for(int i=1;i<=n;i++) ed[i].clear(); memset(du,0,sizeof(du));tim=0;ans=0; memset(tag,0,sizeof(tag)); } inline void getans(){ for(int i=1;i<=n;i++){ tim++; for(int j=0;j<ed[i].size();j++) { int v=ed[i][j];tag[v]=tim; } for(int j=0;j<ed[i].size();j++){ int v=ed[i][j]; if(du[v]<du[i]||(du[v]==du[i]&&v<i)){ int cnt=0; for(int k=0;k<ed[v].size();k++) if(tag[ed[v][k]]==tim) cnt++; ans+=(long long)cnt*(cnt-1)/2; } } } } int main() { T=R(); while(T--){ n=R(),m=R();pre();int a,b; for(int i=1;i<=m;i++) a=R(),b=R(),du[a]++,du[b]++,ed[a].push_back(b),ed[b].push_back(a); getans();cout<<ans<<endl; } }
以上是关于NOIP2017赛前模拟10月30日总结的主要内容,如果未能解决你的问题,请参考以下文章