zoukankan      html  css  js  c++  java
  • 17.10.10

    • 上午
      • 模拟考试(大悲催…)
        • Prob.1(WA

          一个套路,没做过真的好难想出来

          简化题目:

          对于一个整数序列,把任意一个元素修改为任意一个整数为一次操作,问最少需要几次操作可以使得序列(严格)单调上升。

          开始想的是求一个LIS(最长上升子序列),然后发现不对,因为只能修改为整数。

          然后就想不出来了,555

          正解:

          把序列的每个元素的值减去该元素的标号,即a[ i ]-=i ;

          然后再求一个最长不下降子序列,这样求出来的最长序列可以保证:在该最长不下降子序列中的元素不修改的情况下,其他元素一定可以修改成功。

          代码:

          #include<cstdio>
          #include<cstring>
          #include<iostream>
          #include<algorithm>
          using namespace std;
          int lson[100005],rson[100005],key[100005],t[100005],now[100005];
          int n,cnt;
          void DFS(int u){
          	if(lson[u]) DFS(lson[u]);
          	++cnt; t[cnt]=key[u]-cnt;
          	if(rson[u]) DFS(rson[u]);
          }
          void LIS(){
          	cnt=0;
          	for(int i=1;i<=n;i++){
          		if(!cnt||now[cnt]<=t[i]){
          			now[++cnt]=t[i];
          		}
          		else{
          			int l=upper_bound(now+1,now+cnt+1,t[i])-now;
          			now[l]=t[i];
          		}
          	}
          	printf("%d",n-cnt);
          }
          int main(){
          	freopen("binary.in","r",stdin);
          	freopen("binary.out","w",stdout);
          	scanf("%d",&n);
          	for(int i=1;i<=n;i++) scanf("%d",&key[i]);
          	for(int i=2,a,b;i<=n;i++){
          		scanf("%d%d",&a,&b);
          		if(!b) lson[a]=i;
          		else rson[a]=i;
          	}
          	DFS(1);
          	LIS();
          	return 0;
          }
          
    • Prob.2(AC

      一个小技巧:一个序列区间的gcd如果等于该区间的最小值,那么这个区间的所有数都可以被该最小值整除。

      本题两个ST表维护

    • Prob.3(WA

      image

      神题,记忆化搜索

      (S->P)反向考虑交换操作,如果最后一次交换的是a[i]和a[i+1],那么必然在该次交换之前,a[l]~a[i]的值都小于a[i+1]~a[r]。

      所以对于每个成立的a[i],a[i+1],可以把序列分为两段(左一段右一段),然后递归做相同操作。

      然后回溯时对当前递归层的答案贡献

      =左段的方案数*右段的方案数*C(r-l-1,i-l),这个组合数考虑两边的交换顺序

      代码:

      
      
       1 #include<cstdio>
       2 #include<cstring>
       3 #include<iostream>
       4 using namespace std;
       5 const int mod=1000000007;
       6 int dp[55][55],fac[55],inv[55];
       7 int aa[55],pos[55];
       8 int power(int a,int b)
       9 {
      10     int val=1;
      11     while(b)
      12     {
      13         if(b&1) val=(1ll*val*a)%mod;
      14         a=(1ll*a*a)%mod; b>>=1; 
      15     }
      16     return val;
      17 }
      18 void pre_fac_inv(int n)
      19 {
      20     fac[0]=fac[1]=1;
      21     for(int i=2;i<=n;i++) fac[i]=(1ll*fac[i-1]*i)%mod;
      22     inv[n]=power(fac[n],mod-2);
      23     for(int i=n;i>1;i--) inv[i-1]=(1ll*inv[i]*i)%mod;
      24     inv[0]=inv[1];
      25 }
      26 int C(int m,int n)
      27 {
      28     return 1ll*fac[m]*inv[m-n]%mod*inv[n]%mod;
      29 }
      30 int dfs(int l,int r){
      31     if(l>=r) return 1;
      32     if(dp[l][r]) return dp[l][r];
      33     int maxx[55],minn[55];
      34     memset(maxx,0,sizeof(maxx));
      35     memset(minn,0x3f,sizeof(minn));
      36     int ret=0,numl,numr,ma,mi;
      37     for(int i=l;i<=r;i++){
      38         maxx[i]=aa[i];
      39         if(i!=l) maxx[i]=max(maxx[i],maxx[i-1]);
      40     }
      41     for(int i=r;i>=l;i--){
      42         minn[i]=min(minn[i],aa[i]);
      43         if(i!=r) minn[i]=min(minn[i],minn[i+1]);
      44     }
      45     for(int i=l;i<r;i++){
      46         swap(aa[i],aa[i+1]);
      47         ma=max(maxx[i-1],aa[i]);
      48         mi=min(minn[i+2],aa[i+1]);
      49         if(ma<mi){
      50             numl=dfs(l,i);
      51             numr=dfs(i+1,r);
      52             ret=(1ll*ret+1ll*numl*numr%mod*C(r-l-1,i-l)%mod)%mod;
      53         }
      54         swap(aa[i],aa[i+1]);    
      55     }
      56     return dp[l][r]=ret;
      57 }
      58 int main(){
      59     freopen("swap.in","r",stdin);
      60     freopen("swap.out","w",stdout);
      61     int n;
      62     scanf("%d",&n);
      63     pre_fac_inv(n);
      64     for(int i=1;i<=n;i++) scanf("%d",&aa[i]),aa[i]++;
      65     int ans=dfs(1,n);
      66     printf("%d",ans);
      67     return 0;
      68 }
      View Code
      
      
      
      
      
    • 下午
      • 先改了上午的题
      • 然后绝望的发现入门OJ上的题做不了了!!!
      • 就先把前几天做的12道题的题解贴上。
        • 入门OJ 2036 [Noip模拟题]集合贪心
          将每个数x化为 x=a*(k^b) (a%k!=0) 的形式
          对所有的a排序+离散化
          然后排序x后,从小到大去取,
          取的条件为:当前数的b,与之前取的a与当前数的a相同的且b值最大的那个数的b 差值不为1
          (有点绕,分开描述)
          当前数 x=a1*(k^b)
          之前的那个数 x'=a1*(k^b'),且那个数在这个a1的前提下,b'为最大
          如果 b!=b'+1 则可以取
        代码:
        #include<cstdio>
        #include<cstring>
        #include<iostream>
        #include<algorithm>
        #define ll long long
        using namespace std;
        ll a[100005],c[100005],d[100005],tmp;
        int n,k,m,sub,ans,cnt;
        int main(){
        	scanf("%d%d",&n,&k);
        	for(int i=1;i<=n;i++){
        		scanf("%lld",&a[i]); tmp=a[i];
        		while(tmp%k==0) tmp/=k;
        		c[++m]=tmp;
        	}
        	sort(a+1,a+n+1);
        	sort(c+1,c+m+1); m=unique(c+1,c+m+1)-c-1;
        	for(int i=1;i<=n;i++){
        		tmp=a[i]; cnt=0;
        		while(tmp%k==0) tmp/=k,cnt++;cnt++;
        		sub=lower_bound(c+1,c+m+1,tmp)-c;
        		if(!d[sub]||d[sub]!=cnt-1) ans++,d[sub]=cnt;
        	}	
        	printf("%d",ans);
        	return 0;
        }
        • 入门OJ 2075 [Noip模拟题]调整

          建图:
          首先明确一个观点:
          如果我们把一些边调整为边权为0,
          且计算出起点到终点的最短路值小于等于c
          那么一定可以通过让最短路径上调整过的某些边的边权增加,
          (即一开始就把不把其边权变为0),使得该路径的权值和恰好为c
             
          然后就建一个类似层次图的东西
          第几个层次就表示调整了几条边的权值为0
          对于输入的 u,v,w
          对每个层次 u->v 建边权为w的边
          对每个层次的u->下一个层次的v建一个边权为0的边,经过这条边的话就表示要调整其边权为0
             
          最后从小到大枚举每个层次,若该层次的n号节点的dis<=c,那么该层次就是答案(即调整该层次的序号那么多次)
             
          ...不知为何
          用优先队列优化过的spfa跑得还没有裸的spfa快

          代码:

          #include<queue>
          #include<iostream>
          #include<cstdio>
          #include<cstring>
          using namespace std;
          struct edge{
          	int to,val,next;
          }e[3000000];
          int head[200000],dis[200000];
          bool inq[200000];
          int n,m,c,ent=1;
          void add(int u,int v,int w){
          	e[ent]=(edge){v,w,head[u]};
          	head[u]=ent++;
          }
          void spfa(){
          	memset(dis,0x3f,sizeof(dis));
          	queue<int> q;int u,v;
          	q.push(1);inq[1]=1;dis[1]=0;
          	while(!q.empty()){
          		u=q.front(); q.pop(); inq[u]=0;
          		for(int i=head[u];i;i=e[i].next){
          			v=e[i].to;
          			if(dis[v]<=dis[u]+e[i].val) continue;
          			dis[v]=dis[u]+e[i].val;
          			if(inq[v]) continue;
          			q.push(v);
          			inq[v]=1;
          		}
          	}
          }
          int main(){
          	scanf("%d%d%d",&n,&m,&c);
          	for(int i=1,u,v,w;i<=m;i++){
          		scanf("%d%d%d",&u,&v,&w);
          		for(int j=0;j<=m;j++){
          			add(u+j*n,v+j*n,w);
          			add(u+j*n,v+(j+1)*n,0);
          		}
          	}
          	spfa();
          	for(int i=0;i<=m;i++)
          		if(dis[n+i*n]<=c){
          			printf("%d",i);
          			break;
          		}
          	return 0;
          }
    • 入门OJ 2076 [Noip模拟题]集合

      因为A,B的差值不大于10^6,所以不存在两个数可以靠大于10^6的素数合并
      筛出10^6以内的素数,在筛的同时,用并查集合并。

      代码

      #include<iostream>
      #include<cstdio>
      #include<cstring>
      #define ll long long
      using namespace std;
      ll MAXN=1000000;
      ll prime[1000006],fa[2000006];
      bool np[1000006];
      ll ff,ans,A,B,P,cnt;
      ll find(ll x){
      	return fa[x]==x?x:fa[x]=find(fa[x]);
      }
      void find_and_work(){
      	for(int i=1;i<=B-A+1;i++) fa[i]=i;
      	
      	for(ll i=2;i<=MAXN;i++){
      		if(!np[i]){
      			prime[++cnt]=i;
      			if(i>=P){
      				ff=0;
      				for(ll j=((A-1)/i+1)*i;j<=B;j+=i){
      					int f=find(j-A+1);
      					if(!ff) ff=f;
      					else fa[f]=ff;
      				}
      			}
      		}
      		for(ll j=1;j<=cnt&&prime[j]<=MAXN/i;j++){
      			np[i*prime[j]]=1;
      			if(i%prime[j]==0) break;
      		}
      	}
      }
      
      int main(){
      	scanf("%lld%lld%lld",&A,&B,&P);
      	MAXN=min(MAXN,B);
      	find_and_work();
      	for(ll i=1;i<=B-A+1;i++) if(find(i)==i) ans++;
      	printf("%lld",ans);
      	return 0;
      }
    • 入门OJ 2077 [Noip模拟题]购买

      按c排序后模拟即可

      代码

      #include<iostream>
      #include<cstdio>
      #include<cstring>
      #include<algorithm>
      #define ll long long
      using namespace std;
      struct goods{
      	ll k,c;
      	bool operator <(const goods &rtm) const{
      		return c<rtm.c;
      	}
      }g[105];
      ll n,b=1,m,ans,t;
      int main(){
      	scanf("%lld",&n);
      	for(ll i=1;i<=n;i++) scanf("%lld%lld",&g[i].k,&g[i].c);
      	sort(g+1,g+n+1);
      	scanf("%lld",&t);
      	ll i=1;
      	for(ll j=1,x=0,y=0,z=0;j<=t;j++){
      		scanf("%lld",&x);z=y; y=x; x=x-z;
      		while(x&&i<=n){
      			while(g[i].k<=x&&i<=n){
      				ans+=g[i].k*g[i].c*j;
      				x-=g[i].k;
      				i++;
      			}
      			if(i<=n){
      			ans+=x*g[i].c*j;
      			g[i].k-=x;
      			x=0;
      			}
      		}
      	}
      	while(i<=n){
      		ans+=g[i].k*g[i].c*(t+1);
      		i++;
      	}
      	printf("%lld",ans);
      	return 0;
      }
      
    • 入门OJ 2078 [Noip模拟题]填充棋盘

      看题解吧(看不到了诶)
      神奇组合题。

      代码

      #include<cstdio>
      #include<cstring>
      #include<iostream>
      using namespace std;
      const int mod=1000000007;
      int n,m,ans;
      int pow(int a,int b){
      	int val=1;
      	while(b){
      		if(b&1) val=1ll*val*a%mod;
      		a=1ll*a*a%mod;
      		b>>=1;
      	}
      	return val;
      }
      int main(){
      	scanf("%d%d",&n,&m);
      	ans=(1ll*6*(1ll*pow(2,n)+1ll*pow(2,m))-24)%mod;
      	printf("%d",ans);
      	return 0;
      }
      
    • 入门OJ 2081 [Noip模拟题]画山

      dp(背包+递推) 好题

      定义dp[i][j]表示终点在(i,j)的方法数,
      然后每次枚举线段,从前面转移过来:
      dp[i][j]+=dp[i-a],[j-b]
      显然有重复呢。
       
      为了去重,把斜率加入dp状态,
      dp[i][j][k]:表示终点在(i,j)时,且到达改点用的是斜率编号为k的线段。
      目的是每次转移时不能从相同的k转移
      此时,就不能类同上面一样枚举每个线段来转移,(否则会少记录方案)
      而是应该先预处理,把相同斜率的线段归为一组,然后对每一组跑一个物品无限的背包,
      计算出该斜率下可以延伸多长
      然后dp时,枚举每一组斜率,然后枚举背包跑出的可以到达的距离,然后转移。

      O(N*N*M*P)

      代码:

      #include<cstdio>
      #include<cstring>
      #include<iostream>
      #include<algorithm>
      #define ll long long
      using namespace std;
      const ll mod=1000000007;
      struct segment{
      	int a,b;
      	bool operator <(const segment &rtm) const{
      		return b*rtm.a<rtm.b*a;
      	}
      }seg[105];
      struct group{
      	int a,b;
      	bool can[105];
      }gro[105];
      ll dp[105][105][105],s[105][105];
      int gnt,n,m,p;
      int main(){
      	scanf("%d%d%d",&n,&m,&p);
      	for(int i=1;i<=p;i++) scanf("%d%d",&seg[i].a,&seg[i].b);
      	sort(seg+1,seg+p+1);
      	int st=1; bool *f;
      	for(int I=1;I<=p+1;I++){
      		if(I==p+1||(seg[I].b*seg[st].a!=seg[I].a*seg[st].b)){
      			++gnt;
      			gro[gnt].a=seg[st].a; 
      			gro[gnt].b=seg[st].b;
      			f=gro[gnt].can; f[0]=1;
      			for(int i=st;i<I;i++)
      				for(int j=seg[i].a;j<=n;j++)
      					f[j]=f[j]|f[j-seg[i].a];
      			st=I;
      		}
      	}
      	s[0][0]=1;
      	for(int i=0;i<=n;i++)
      		for(int j=0;j<=m;j++)
      			for(int k=1;k<=gnt;k++){
      				for(int o=1;o<=n;o++) if(gro[k].can[o]){
      					int ii=o,jj=ii*gro[k].b/gro[k].a;
      					if(i-ii<0||j-jj<0||j-jj>m) break;
      					dp[i][j][k]=(dp[i][j][k]+s[i-ii][j-jj]-dp[i-ii][j-jj][k]+mod)%mod;
      				}
      				s[i][j]=(s[i][j]+dp[i][j][k]+mod)%mod;
      			}
      	printf("%lld",s[n][0]);
      	return 0;
      }
      
    • 入门OJ 2082 [Noip模拟题]益智游戏

      益智好题
         
      可以明确的是两个人如果会走到相同的一些点,那么这些点一定是连续的
      (都是走最短路嘛)
         
      对于每个人,求出他的最短路DAG图(最短路不止一条啦)
         
      怎么求这个对短路DAG图呢?
      对起点和终点分别跑一次最短路,得到两个dis数组(dis1是从起点跑得,dis2是从终点跑的)
      对于一条边的 u v w,若dis1[u]+dis2[v]+w==dis(起点->终点),那么这条边就在最短路DAG中
         
      然后呢,取出两个人的最短路DAG图中都走的边构成一个新图
      对新图按按拓扑序进行最长路dp。
         
      特判两个人的最短路DAG图是否有相交,
      相交的话,答案要加一,因为dp值是最长路,而要求的是点数
      不相交的话,就不用加了,因为ans本来就等于0;

      代码:

      #include<queue> 
      #include<cstdio>
      #include<cstring>
      #include<iostream>
      #define INF 0x3f3f3f3f3f3f3f3f
      #define ll long long
      #define node(a,b) (node){a,b}
      using namespace std;
      struct node{
      	ll id,d;
      	bool operator <(const node &rtm) const{
      		return d>rtm.d;
      	}
      };
      struct edge{
      	ll from,to,val,next; 
      }e1[200005],e2[200005],e3[200005];
      ll head1[50005],head2[50005],head3[50005];
      ll dis1[50005],dis2[50005],dis3[50005],in[50005];
      bool fg[50005],ve[200005],xj;
      ll n,m,A,B,C,D,ent1=1,ent2=1,ent3=1,disab,discd,ans;
      void add(ll u,ll v,ll w,ll *head,edge *e,ll &ent){
      	e[ent]=(edge){u,v,w,head[u]}; head[u]=ent++;
      }
      ll dijistra(ll st,ll ed,ll *head,ll *dis,edge *e){
      	static bool vis[50005]; 
      	memset(vis,0,sizeof(bool)*(n+3));
      	memset(dis,0x3f,sizeof(ll)*(n+3));
      	priority_queue<node>q; node now; 
      	ll u,v; dis[st]=0;
      	q.push(node(st,0)); 
      	while(!q.empty()){
      		now=q.top(); q.pop(); u=now.id;
      		if(vis[u]) continue; vis[u]=1;
      		for(ll i=head[u];i;i=e[i].next){
      			v=e[i].to;
      			if(vis[v]||dis[v]<=dis[u]+e[i].val) continue;
      			dis[v]=dis[u]+e[i].val;
      			q.push(node(v,dis[v]));
      		}
      	}
      	return dis[ed];
      }
      void topo(ll st,ll ed,ll *head,ll *dis,edge *e){
      	queue<int>q;
      	for(int i=1;i<=n;i++) if(!in[i]) q.push(i);
      	while(!q.empty()){
      		int u=q.front(); q.pop();
      		ans=max(ans,dis[u]);
      		for(int i=head[u];i;i=e[i].next){
      			int v=e[i].to;
      			dis[v]=max(dis[v],dis[u]+1);
      			in[v]--;
      			if(!in[v])q.push(v);
      		}
      	}
      }
      int main(){
      	//freopen("in.in","r",stdin);
      	scanf("%lld%lld",&n,&m);
      	for(ll i=1,a,b,c;i<=m;i++){
      		scanf("%lld%lld%lld",&a,&b,&c);
      		add(a,b,c,head1,e1,ent1);
      		add(b,a,c,head2,e2,ent2);
      	}
      	scanf("%lld%lld%lld%lld",&A,&B,&C,&D);
      	disab=dijistra(A,B,head1,dis1,e1);
      	disab=dijistra(B,A,head2,dis2,e2);
      	if(disab==INF){printf("-1");return 0;}
      	for(int i=1;i<ent1;i++){
      		int u=e1[i].from,v=e1[i].to,w=e1[i].val;
      		if(dis1[u]+dis2[v]+w==disab) fg[u]=fg[v]=1,ve[i]=1;
      	}
      	discd=dijistra(C,D,head1,dis1,e1);
      	discd=dijistra(D,C,head2,dis2,e2);
      	if(discd==INF){printf("-1");return 0;}
      	for(int i=1;i<ent1;i++){
      		int u=e1[i].from,v=e1[i].to,w=e1[i].val;
      		if(dis1[u]+dis2[v]+w==discd){
      			if(fg[u]||fg[v]) xj=1;
      			if(!ve[i]) continue;
      			add(u,v,w,head3,e3,ent3);
      			in[v]++;			
      		}
      	}
      	topo(C,D,head3,dis3,e3);
      	if(xj) ans++;
      	printf("%lld",ans);
      	return 0;
      }
    • 入门OJ 2083 [Noip模拟题]围篱笆

      和上题一样,也是一道"益智"题

      代码:

      #include<cmath> 
      #include<cstdio>
      #include<cstring>
      #include<iostream>
      using namespace std;
      const double pi=acos(-1);
      int N;
      int main(){
      	while(1){
      		scanf("%d",&N);
      		if(!N) break;
      		printf("%.2lf
      ",1.0*N*N/pi/2);
      	}
      	return 0;
      }
    • 入门OJ 2084 [Noip模拟题]点

      假题,其实选的点可以和原来的点重合。

      代码:

      #include<cstdio>
      #include<cstring>
      #include<iostream>
      #include<algorithm>
      #include<windows.h> 
      #define happy_check(); 
      int RESULT=MessageBox(NULL,TEXT("Are you happy?"),"Just click on it" ,MB_YESNO);if(RESULT==IDNO){
      MessageBox(NULL,TEXT("Poor guy!
      Hope you can be better."),"You are not happy?" ,MB_OK);return 0;}
      using namespace std;
      int x[10005],y[10005];
      int n,lx,ly,cnt,xx,yy,ans;
      int abs(int a){
      	return a<0?-a:a;
      }
      int main(){
      	//happy_check();
      	scanf("%d",&n);
      	for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
      	sort(x+1,x+n+1); sort(y+1,y+n+1);
      	if(n&1) cnt=1,xx=x[n/2+1],yy=y[n/2+1]; 
      	else{
      		xx=x[n/2]; lx=x[n/2+1]-x[n/2]+1;
      		yy=y[n/2]; ly=y[n/2+1]-y[n/2]+1;
      		cnt=lx*ly;
      	}
      	for(int i=1;i<=n;i++) ans+=abs(xx-x[i]);
      	for(int i=1;i<=n;i++) ans+=abs(yy-y[i]);
      	printf("%d %d",ans,cnt);
      	return 0;
      }
      
    • 入门OJ 2085 [Noip模拟题]身高

      对于每个约束(a,b)
      那么a,b之间的应该都比a和b小,所以就差分使得该区间整体小一
      注意有重复的(a,b),要去重,否则WA

      (怎么有一个输入的东西没用上?)

      代码:

      #include<cstdio>
      #include<cstring>
      #include<iostream>
      #include<algorithm>
      using namespace std;
      struct cons{
      	int a,b;
      	bool operator <(const cons &rtm) const{
      		return a!=rtm.a?a<rtm.a:b<rtm.b;
      	}
      }t[100005];
      int dif[100005];
      int N,I,H,R;
      int main(){
      	scanf("%d%d%d%d",&N,&I,&H,&R);
      	for(int i=1;i<=R;i++){
      		scanf("%d%d",&t[i].a,&t[i].b);
      		if(t[i].a>t[i].b) swap(t[i].a,t[i].b);
      	}
      	sort(t+1,t+R+1);
      	for(int i=1,j=0;i<=R;i++){
      		if(t[i].a==t[j].a&&t[i].b==t[j].b) continue;
      		dif[t[i].a+1]-=1;
      		dif[t[i].b]+=1;
      		j=i;
      	}
      	for(int i=1;i<=N;i++){
      		H+=dif[i];
      		printf("%d
      ",H);
      	}
      	return 0;
      }
      
    • 入门OJ 2087 [Noip模拟题]lucky

      裸的数位Dp
      输入的数不超过10^20,可能爆long long(包括unsigned long long)
      所以用字符串读入
      (一直wa,最后才发现读入出错了)

      代码:

      #include<cstdio>
      #include<cstring>
      #include<iostream>
      #define ll long long
      using namespace std;
      ll dp[30][12][2];
      ll N,tail,num[30]; 
      ll dfs(int p,int last,bool ach,bool up){
      	if(p>tail) return ach;
      	if(!up&&dp[p][last][ach]!=-1) return dp[p][last][ach];
      	ll ret=0; int r=up?num[p]:9;
      	for(int i=0;i<=r;i++) 
      		ret+=dfs(p+1,i,ach||(last==4&&i==9),up&&i==r);
      	if(!up) return dp[p][last][ach]=ret;
      	return ret;
      }
      int main(){
      	num[++tail]=getchar()-'0';
      	while(num[tail]<0||num[tail]>9) num[tail]=getchar()-'0';
      	while(num[tail]<=9&&num[tail]>=0) num[++tail]=getchar()-'0';
      	tail--;
      	memset(dp,-1,sizeof(dp));
      	cout<<dfs(1,0,0,1);
      	return 0;
      }
      
    • 入门OJ 2088 [Noip模拟题]小球

      模拟,做了超过100000次就停下来

      代码:

      #include<cstdio>
      #include<cstring>
      #include<iostream>
      using namespace std;
      int A,B,cnt; 
      int main(){
      	scanf("%d%d",&A,&B);
      	while(1){
      		if(A>B) swap(A,B);
      		if(!A) break;
      		B-=A;	A+=A;
      		cnt++;
      		if(cnt>100000){
      			printf("-1");
      			return 0;
      		}
      	}
      	printf("%d",cnt);
      	return 0;
      }
    • 晚上
      • BZOJ 1011 [HNOI2008]遥远的行星

        扯题。
            利用题目给的答案误差(大佬博客 ↓)
           
        http://www.cnblogs.com/Sunnie69/p/5575626.html

        代码:

        #include<cstdio>
        #include<cstring>
        #include<iostream>
        #define MAXN 100005 
        using namespace std;
        const double eps=1e-8;
        double m[MAXN],s[MAXN];
        double A,ans;int n,p,B;
        int main(){
            scanf("%d%lf",&n,&A);
            for(int i=1;i<=n;i++) scanf("%lf",&m[i]),s[i]=s[i-1]+m[i];
            p=min(2000,n);
            for(int i=1;i<=p;i++){
                ans=0;
                B=(int)(A*i+eps);
                for(int j=1;j<=B;j++) ans+=m[j]/(1.0*i-j);
                printf("%.6lf
        ",ans*m[i]);
            }
            for(int i=p+1;i<=n;i++){
                B=(int)(A*i+eps);
                ans=m[i]*s[B]/(1.0*i-1.0*B/2);
                printf("%.6lf
        ",ans);
            }
            return 0;
        }
      • BZOJ 1013 [JSOI2008]球形空间产生器sphere

        设出中心的多维坐标
        由给出的n+1个点得出n个等式,
        用高斯消元计算出线性方程的各个元的值
           
        至于高斯消元,自己模拟就好了。

        代码:

        #include<cstdio>
        #include<cstring>
        #include<iostream>
        using namespace std;
        double k[15][15],w[2][15],d[15];
        int n;
        void Gaussian(int p){
        	if(p>n) return;
        	double b,val=0;
        	for(int r=p+1;r<=n;r++){
        		b=k[r][p]/k[p][p];
        		for(int i=p;i<=n+1;i++)
        			k[r][i]=k[r][i]-k[p][i]*b;
        	}
        	Gaussian(p+1);
        	for(int i=p+1;i<=n;i++)
        		val+=d[i]*k[p][i];
        	d[p]=(k[p][n+1]-val)/k[p][p];
        }
        int main(){
        	int cur=0;
        	scanf("%d",&n);
        	for(int i=1;i<=n;i++)scanf("%lf",&w[cur][i]);
        	for(int r=1;r<=n;r++){
        		cur^=1;
        		for(int i=1;i<=n;i++)scanf("%lf",&w[cur][i]);
        		for(int i=1;i<=n;i++){
        			k[r][i]=2*(w[cur^1][i]-w[cur][i]);
        			k[r][n+1]=k[r][n+1]+w[cur^1][i]*w[cur^1][i]-w[cur][i]*w[cur][i];
        		}
        	}
        	Gaussian(1);
        	for(int i=1;i<n;i++)
        		printf("%.3lf ",d[i]);
        	printf("%.3lf",d[n]);
        	return 0;
        }
        
      • BZOJ 1012 [JSOI2008]最大数maxnumber

        可以线段树。
         
        注意到如果向队尾加入一个元素,
        且它前面的元素比它小的话,那么无论怎么询问,它前面的元素都不可能贡献答案
        所以维护一个单调栈,有了单调性后,二分寻找答案。

        代码:

        #include<cstdio>
        #include<cstring>
        #include<iostream>
        #include<algorithm> 
        using namespace std;
        int num[200005],pos[200005];
        int N,D,t,cnt,top,l;
        int main(){
        	scanf("%d%d",&N,&D);
        	char com; int x;
        	for(int i=1;i<=N;i++){
        		scanf(" %c%d",&com,&x);
        		if(com=='A'){
        			++cnt; x=(x+t)%D;
        			while(top&&num[top]<=x) top--;
        			num[++top]=x;
        			pos[top]=cnt;
        		}
        		else if(com=='Q'){
        			x=cnt-x+1;
        			l=lower_bound(pos+1,pos+top+1,x)-pos;
        			t=num[l];
        			printf("%d
        ",t);
        		}
        	}
        	return 0;
        }
        
  • 相关阅读:
    使用 asp.net mvc和 jQuery UI 控件包
    ServiceStack.Redis 使用教程
    HTC T8878刷机手册
    Entity Framework CodeFirst 文章汇集
    2011年Mono发展历程
    日志管理实用程序LogExpert
    使用 NuGet 管理项目库
    WCF 4.0路由服务Routing Service
    精进不休 .NET 4.0 (1) asp.net 4.0 新特性之web.config的改进, ViewStateMode, ClientIDMode, EnablePersistedSelection, 控件的其它一些改进
    精进不休 .NET 4.0 (7) ADO.NET Entity Framework 4.0 新特性
  • 原文地址:https://www.cnblogs.com/zj75211/p/7646581.html
Copyright © 2011-2022 走看看