JXNU 2015-11
来源:互联网 发布:笔记本文具 知乎 编辑:程序博客网 时间:2024/06/05 23:31
由于 G 为 a,b 的最大公约数,那么 G 肯定是 a 的约数。由于 L 为 a,b 的最小公倍数,那么 L 肯定是 a 的倍数,也就是说 a 是 L 的约数。
既然 G 是 a 的约数,a 是 L 的约数,那么,G 必然是 L 的约数。如果 L 不能被 G 整除,那么必然不存在满足条件的 a,b
如果 L 能被 G 整除,那么由于 G<=a<=L,G<=b<=L.则满足条件的最小的 a 必然是 G,此时 b 必然等于 L。
故只要判断 L 是否能被 G 整除即可。直接上高精度除法模板,或 JAVA 大数搞之。
1002
首先,m>n 必然会冲突,直接输出 0
考虑 m<=n 的情形,很容易发现 ans=A(n,m)*C(n,m)1003
直接模拟即可,可以 dfs 实现,也可以直接非递归实现
1004
1001~1004 并不是我出的题,验题的时候我是这样做的,以 O(n^3)的复杂度
暴力出前 20 个数的结果,然后发现有规律,至于规律具体是什么 ,直接http://oeis.org/之(一个找数列规律的网站,很强大,很多题在推不出公式的情况
下可以这么搞)
1005
难度定位:中等题
归类:数学题复杂度:O(n)
事实上,行列式可以化简成 a[1]*x^(n-1)+a[2]*x^(n-2)+...+a[n-1]*x^1+a[n]
如果直接算 a[1]*x^(n-1)%mod,需要用快速幂。
这里完全可以以 o(n)的复杂度先预处理出 x^i,(0<=i<=n-1)
然后再以 o(n)的复杂度 ans+=a[i]*x[n-i]即可,(1<=i<=n)
故总复杂度 O(n)
1006
难度定位:中等题
归类:线段树||树状数组
复杂度:O(n*log(n))
由于 i<j<k,a[i]<=a[j]<=a[k]最快的方法便是枚举 a[j],对于 a[j],如果能快速求出前面有多少个数比它小(逆序数),后面有多少个数比它大就好了。恰好,我们可以用线段树维护,并快速求
出。具体做法如下:
第一步,由于数据比较大,故离散化之(离散化三步走,排序,去重,二分)。(这部分复杂度 O(n*log(n)))
第二步,定义 left,right 数组,left[i],意为在 i 前面有多少个数小于等于 a[i],right[i],在 i 后面有多少个数大于等于 a[i]。那么如何求他们呢?例如求 left 数组,
从前往后枚举 i,对于 a[i],假设他离散化后的位置是 p,那么在线段树中查询区间[1,p]的和即可(即为小于等于 a[i]数的个数),然后,更新线段树维护 p 点的区间
的值即可。right 数组求法类似。只不过要从后往前枚举 i。 (这部分也是 O(n*log(n)))
其实上面的做法就是线段树||树状数组求逆序数的思想。
第三步,由乘法原理可知,枚举 i,然后 ans+=left[i]*right[i]即可。(这部分 O(n))
故总复杂度 O(n*log(n))
1007
难度定位:简单题
归类:模拟题
复杂度:O(n)
先把开奖的号码用数组 hash 一下。
对于每组数据与开奖比对,只需要到 hash 数组中查询即可。
1008
难度定位:难题
归类:最小费用最大流
复杂度:O(n^3)
题意:
给定一个有向图,必须用若干个环来覆盖整个图,要求这些覆盖的环的权值最小。
思路:
最小费用最大流,复杂度 O(n^3)
原图每个点 u 拆为 u 和 u' ,从源点引容量为 1 费用为 0 的边到 u ,从u' 引相同性质的边到汇点,若原图中存在 (u, v) ,则从 u 引容量为 1 费用为
c(u, v) 的边到 v' 。这里源模拟的是出度,汇模拟的是入度,又每个点的出度等于入度等于 1 ,那么如果最大流不等于顶点数 n ,则无解;否则,答案就是最小费用。
1001
#include<iostream>#include<cstring>#include<algorithm>using namespace std;const int L=210;int sub(int *a,int *b,int La,int Lb){ if(La<Lb) return -1;//如果a小于b,则返回-1 if(La==Lb) { for(int i=La-1;i>=0;i--) if(a[i]>b[i]) break; else if(a[i]<b[i]) return -1;//如果a小于b,则返回-1 } for(int i=0;i<La;i++)//高精度减法 { a[i]-=b[i]; if(a[i]<0) a[i]+=10,a[i+1]--; } for(int i=La-1;i>=0;i--) if(a[i]) return i+1;//返回差的位数 return 0;//返回差的位数}string div(string n1,string n2,int nn)//n1,n2是字符串表示的被除数,除数,nn是选择返回商还是余数{ string s,v;//s存商,v存余数 int a[L],b[L],r[L],La=n1.size(),Lb=n2.size(),i,tp=La;//a,b是整形数组表示被除数,除数,tp保存被除数的长度 fill(a,a+L,0);fill(b,b+L,0);fill(r,r+L,0);//数组元素都置为0 for(i=La-1;i>=0;i--) a[La-1-i]=n1[i]-'0'; for(i=Lb-1;i>=0;i--) b[Lb-1-i]=n2[i]-'0'; if(La<Lb || (La==Lb && n1<n2)) { //cout<<0<<endl; return n1;}//如果a<b,则商为0,余数为被除数 int t=La-Lb;//除被数和除数的位数之差 for(int i=La-1;i>=0;i--)//将除数扩大10^t倍 if(i>=t) b[i]=b[i-t]; else b[i]=0; Lb=La; for(int j=0;j<=t;j++) { int temp; while((temp=sub(a,b+j,La,Lb-j))>=0)//如果被除数比除数大继续减 { La=temp; r[t-j]++; } } for(i=0;i<L-10;i++) r[i+1]+=r[i]/10,r[i]%=10;//统一处理进位 while(!r[i]) i--;//将整形数组表示的商转化成字符串表示的 while(i>=0) s+=r[i--]+'0'; //cout<<s<<endl; i=tp; while(!a[i]) i--;//将整形数组表示的余数转化成字符串表示的</span> while(i>=0) v+=a[i--]+'0'; if(v.empty()) v="0"; //cout<<v<<endl; if(nn==1) return s; if(nn==2) return v;}int main(){ string a,b; while(cin>>a>>b) { //cout<<div(a,b,1)<<endl; //cout<<div(a,b,2)<<endl; string ans=div(b,a,2); if(ans!="0") cout<<-1<<endl; else cout<<a<<" "<<b<<endl; } return 0;}
1002
#include<iostream>#include<cstdio>#define ULL unsigned long longusing namespace std;const int maxn=35;ULL dp[maxn][maxn*maxn];ULL C(int n,int m){ if(n<m) return 0; ULL ans=1; for(int i=0;i<m;i++) ans=ans*(ULL)(n-i)/(ULL)(i+1); return ans;}ULL A(int n,int m){ if(n<m) return 0; ULL ans=1; for(int i=0;i<m;i++) ans*=(ULL)(n-i); return ans;}ULL fuck(int n,int k){ if(dp[n][k]) return dp[n][k]; return dp[n][k]=A(n,k)*C(n,k);}int main(){ //freopen("in.txt","r",stdin); int n,k,t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&k); printf("%I64u\n",fuck(n,k)); //printf("%I64u\n",A(n,k)); //printf("%I64u\n",C(n,k)); } return 0;}
1003
#include<iostream>#include<cstdio>using namespace std;const int maxn=105;int a[maxn][maxn];void dfs(int x,int y,int n,int m,int num){ if(n==0||m==0) return ; if(n==1) { for(int i=0;i<m;i++) a[x][y+i]=num++; return ; } if(m==1) { for(int i=0;i<n;i++) a[x+i][y]=num++; return ; } for(int i=0;i<m;i++) a[x][y+i]=num++; for(int i=1;i<n-1;i++) a[x+i][y+m-1]=num++; for(int i=m-1;i>=0;i--) a[x+n-1][y+i]=num++; for(int i=n-2;i>0;i--) a[x+i][y]=num++; dfs(x+1,y+1,n-2,m-2,num);}int main(){ int n,m; while(~scanf("%d%d",&n,&m)) { dfs(0,0,n,m,1); for(int i=0;i<n;i++) { for(int j=0;j<m-1;j++) printf("%d ",a[i][j]); printf("%d\n",a[i][m-1]); } } return 0;}
1004
<pre name="code" class="cpp">#include<iostream>#include<cstdio>#define LL long longusing namespace std;const int maxn=1000005;LL dp[maxn];int main(){ //dp[0]=1; //dp[1]=3; //dp[2]=3; // for(int i=2;i<maxn;i++) dp[i]=dp[i-2]+(LL)i*(LL)(i-1)/2; LL n; while(~scanf("%I64d",&n)) //printf("%d\n",dp[n-3]); { n-=4; LL ans=(n+2)*(n+4)*(2*n+3) / 24; printf("%I64d\n",ans); } return 0;}
1005
<pre name="code" class="cpp">#include<iostream>#include<cstdio>#define LL long longusing namespace std;const int maxn=100005;const LL mod=1000000007;int a[maxn];LL X[maxn];int main(){ // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int t,n,x; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&x); for(int i=1;i<=n;i++) scanf("%d",&a[i]); X[0]=1; for(int i=1;i<n;i++) X[i]=(X[i-1]*x)%mod;//预处理出所有的x^i LL ans=0; for(int i=0;i<n;i++) ans=(ans+X[i]*a[n-i])%mod; printf("%I64d\n",ans); } return 0;}
1006
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define LL long long#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int maxn=100005;int a[maxn],b[maxn],Left[maxn],Right[maxn];int sum[maxn<<2];void PushUp(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void build(int l,int r,int rt){ if(l==r) { sum[rt]=0; return ; } int m=(l+r)>>1; build(lson); build(rson); PushUp(rt);}void update(int p,int l,int r,int rt){ if(l==r) { sum[rt]++; return ; } int m=(l+r)>>1; if(p<=m) update(p,lson); else update(p,rson); PushUp(rt);}int query(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R) { return sum[rt]; } int m=(l+r)>>1; int ans=0; if(L<=m) ans+=query(L,R,lson); if(R>m) ans+=query(L,R,rson); return ans;}int main(){ // freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int t,n; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]),b[i]=a[i]; sort(b,b+n);//离散化第一步 int lb=unique(b,b+n)-b;//离散化第二步 build(1,lb,1);//由于离散化后a[i]的范围为[1,lb],故建立一颗维护[1,lb]的和的线段树 for(int i=0;i<n;i++) { int p=upper_bound(b,b+lb,a[i])-b;//离散化第三步 Left[i]=query(1,p,1,lb,1);//查询出小于等于a[i]的数的个数,类似于线段树求逆序数的原理 update(p,1,lb,1);//插入第i个数 } build(1,lb,1); for(int i=n-1;i>=0;i--) { int p=upper_bound(b,b+lb,a[i])-b; Right[i]=query(p,lb,1,lb,1); update(p,1,lb,1); } LL ans=0; for(int i=0;i<n;i++) { ans+=(LL)Left[i]*(LL)Right[i]; //printf("%d %d\n",Left[i],Right[i]); } printf("%I64d\n",ans); } return 0;}1007
#include<iostream>#include<cstdio>#define LL long longusing namespace std;int a[100005][8];int b[8];int vis[40];int n;int ans[10][10];void SetValue(){ ans[6][1]=5000000;ans[6][0]=500000; ans[5][1]=3000;ans[5][0]=200; ans[4][1]=200;ans[4][0]=10; ans[3][1]=10;ans[2][1]=5; ans[1][1]=5;ans[0][1]=5;}void solve(){ fill(vis,vis+40,0); for(int i=0;i<6;i++) vis[b[i]]=1; LL sum=2*n; for(int i=0;i<n;i++) { int k=0,p; for(int j=0;j<6;j++) k+=vis[a[i][j]]; p=(a[i][6]==b[6]); sum-=ans[k][p]; } printf("%I64d\n",sum);}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); SetValue(); int t; scanf("%d",&t); while(t--) { for(int i=0;i<7;i++) scanf("%d",&b[i]); scanf("%d",&n); for(int i=0;i<n;i++) for(int j=0;j<7;j++) scanf("%d",&a[i][j]); solve(); } return 0;}
1008
#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<sstream>#include<fstream>#include<vector>#include<map>#include<stack>#include<list>#include<set>#include<queue>#define LL long long#define lson l,m,rt<<1#define rson m+1,r,rt<<1 | 1using namespace std;const int maxn=100005,inf=1<<29;int n,m,V;typedef pair<int,int>P;struct edge{ int to,cap,cost,rev;};vector<edge>G[maxn];int h[maxn];//¶¥μãμÄêÆint dist[maxn];//×î¶ì¾ààëint prevv[maxn],preve[maxn];void add_edge(int from,int to,int cap,int cost){ G[from].push_back((edge){to,cap,cost,G[to].size()}); G[to].push_back((edge){from,0,-cost,G[from].size()-1});}void Dijkstra(int s,int t){ priority_queue<P,vector<P>,greater<P> >q; fill(dist,dist+V,inf); dist[s]=0; q.push(P(0,s)); while(q.size()) { P p=q.top();q.pop(); int v=p.second; if(dist[v]<p.first) continue; for(int i=0;i<G[v].size();i++) { edge &e=G[v][i]; if(e.cap>0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]) { dist[e.to]=dist[v]+e.cost+h[v]-h[e.to]; prevv[e.to]=v; preve[e.to]=i; q.push(P(dist[e.to],e.to)); } } }}int min_cost_flow(int s,int t,int f){ int res=0; fill(h,h+V,0); while(f>0) { Dijkstra(s,t); if(dist[t]==inf) return -1; for(int v=0;v!=V;v++) h[v]+=dist[v]; int d=f; for(int v=t;v!=s;v=prevv[v]) d=min(d,G[prevv[v]][preve[v]].cap); f-=d; res+=d*h[t]; for(int v=t;v!=s;v=prevv[v]) { edge &e=G[prevv[v]][preve[v]]; e.cap-=d; G[v][e.rev].cap+=d; } } return res;}int main(){ //freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); while(~scanf("%d%d",&n,&m)) { V=2*n+2; for(int i=0;i<=V;i++) G[i].clear(); int s=0,t=2*n+1; for(int i=1;i<=n;i++) add_edge(s,i,1,0); for(int i=1;i<=n;i++) add_edge(i+n,t,1,0); while(m--) { int x,y,w; scanf("%d%d%d",&x,&y,&w); add_edge(x,y+n,1,w); } printf("%d\n",min_cost_flow(s,t,n)); } return 0;}
- JXNU 2015-11
- JXNU-2015-10-月赛
- JXNU暑期选拔赛题解
- Jxnu Group Programming Ladder Tournament 2017题解
- JXNU 2017 校ACM程序设计竞赛(16级)题解
- http://jxnu.acmclub.com/index.php?app=problem_title&id=468&problem_id=1017
- 2015-2-11
- 3/11/2015
- 2015/4/11
- 2015 - 04 - 11
- 2015-6-11
- 2015-08-11
- [2015-08-11] python022
- 2015/9/11
- 2015-11-1日志
- 2015/11/1
- 2015-11-05
- 2015/11/5 笔记
- 数据库锁(一)
- Java中this分类以及在各分类下的用法或规则
- 函数与优化
- UILable的lineBreakMode
- NZT-ttssos的使用教程 安装可免费测试自动测试一天 推荐NEO版本 非v3 v8 als ifaker8
- JXNU 2015-11
- 仿QQ5.0侧滑菜单—进阶篇
- json数据的解析
- 1009. Product of Polynomials (25)
- 工业4.0---感悟
- redis 初识
- A*寻路算法入门(二)
- MyEclipse建立SpringMVC入门HelloWorld项目
- Android学习之四大组件简单介绍