• 训练报告 (2014-2015) 2014, Samara SAU ACM ICPC Quarterfinal Qualification Contest


    Solved A Gym 100488A Yet Another Goat in the Garden
      B Gym 100488B Impossible to Guess
    Solved C Gym 100488C Lost Temple
    Solved D Gym 100488D Toy Soldiers
    Solved E Gym 100488E Just Change a Word
    Solved F Gym 100488F Two Envelopes
    Solved G Gym 100488G Change-making Problem
      H Gym 100488H Tony Hawk's Pro Skater
    Solved I Gym 100488I Map Coloring
      J Gym 100488J Hyperdromes Strike Back
    Solved K Gym 100488K Two Pirates
      L Gym 100488L Two Heads Are Better
    Solved M Gym 100488M Construct a Permutation

    链接:2014, Samara SAU ACM ICPC Quarterfinal Qualification Contest

    打了不到2个小时,3星

    AC 4/13 
    真滴菜
    A了4个题,然后挂机,然后溜了...
    G 题没过滤掉无效情况 
    D 没考虑一开始就不用涂的情况 

    实际上
    如果把M题,C题的时间拿来试A的题意,估计秒了
    然后把I题的思路勇敢的推倒,搞个暴力,稳到5-6题也是可能的…

    题解:

    A 计算几何 

    出题人没说清楚题意,简直智障,求的确实是百分比,和我猜的一样...

    很显然,把三个角的未覆盖放在一起,可以得到一个黑洞的外接三角形...

    小三角形和大三角形的面积之比就是(黑洞的半径/大三角形内接圆半径)^2

    大三角形的面积可以用海伦公式得到

    然后小三角形的面积减去黑洞的面积就是没有覆盖的面积...

    写的时候我一度以为是直角三角形..

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    int casn,n,m,k;
    int a1[maxn],a2[maxn];
    int main(){
    //#define test
    #ifdef test
    	freopen("in.txt","r",stdin);freopen("out1.txt","w",stdout);
    #endif
    
    	double a,b,c,r;
    	double PI=2.0*acos(0);
    	double num[3];
    	while(cin>>num[0]>>num[1]>>num[2]>>r){
    		sort(num,num+3);
    		a=num[0],b=num[1],c=num[2];
    		double l=(a+b+c)/2.0;
    		double sum=sqrt(l*(l-a)*(l-b)*(l-c));
    		double R=2.0*sum/(a+b+c);
    		double ss=sum*(r/R)*(r/R)-r*r*PI;
    		double ans=(1.0-ss/sum);
    		printf("%.16f
    ",ans);
    	}
    
    #ifdef test
    	fclose(stdin);fclose(stdout);system("out1.txt");
    #endif
    	return 0;
    }

    C

    a*b=k(a+b)

    给k 求所有的a和b

    推一下公式 发现可以转化为a=k+(k^2)/(b-k)

    所以只要得到k^2的所有因子,然后把这些因子+k就是b,k^2/这些因子再+k就是a...

    显然 k^2的因字即k的因子,而k^2=k*k(废话),因此任意两个k的因子相乘,也一定是k^2的因子..

    然后暴力就行了...

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    ll casn,n,m,k;
    set<ll> vis;
    ll num[maxn];
    int cnt=0;
    int main(){
    //#define test
    #ifdef test
    	freopen("in.txt","r",stdin);freopen("out1.txt","w",stdout);
    #endif
    	while(cin>>k){
    		cnt=0;
    		for(int i=1;i*i<=k;i++){
    			if(k%i) continue;
    			num[cnt++]=i;
    			if(i*i!=k) num[cnt++]=k/i;
    		}
    		vis.clear();
    		for(int i=0;i<cnt;i++){
    			for(int j=0;j<cnt;j++){
    				vis.insert(num[i]*num[j]);
    			}
    		}
    		cout<<vis.size()<<endl;
    		for(auto i=vis.begin();i!=vis.end();i++){
    			cout<<(*i+k)<<' '<<k+(k*k)/(*i)<<endl;
    		}
    	}
    #ifdef test
    	fclose(stdin);fclose(stdout);system("out1.txt");
    #endif
    	return 0;
    }
    

    D

    水题

    用map保存种颜色的数量,如果修改的过程中数量为零,则删除

    当size==1的时候 结束

    注意一开始就size==1的情况....

    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <stdio.h>
    #include <map>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    int casn,n,m,k;
    int a,b,c;
    int num[maxn];
    map<int,int> vis;
    
    int main(){
    // #define test
    #ifdef test
    	freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
    #endif
    
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		scanf("%d",&num[i]);
    		vis[num[i]]++;
     }
    
    	cin>>m;
    	int ans=0;
    	if(vis.size()==1) {
    			ans=-1;
    	}
    	for(int i=1;i<=m;i++){
    		scanf("%d %d",&a,&b);
    		if(ans) continue;
    		if(vis.size()==1) {
    			ans=i;
    		}
    		vis[num[a]]--;
    		if(vis[num[a]]==0) vis.erase(num[a]);
    		vis[b]++;
    		num[a]=b;
    		if(vis.size()==1) {
    			ans=i;
    		}
    	}
    	if(!ans)cout<<-1<<endl;
    	else cout<<max(ans,0)<<endl;
    
    
    #ifdef test
    	fclose(stdin);fclose(stdout);system("out.txt");
    #endif
    	return 0;
    }
    

    E

    水题

    给一个字符串

    每次找两个相邻的不同字母删除,问是否能删光

    我想递推,但zc直接想出了只要统计是否有一种字符数量大于一半,大于则不可能

    逻辑也比较显然,只要种类不是1种 就肯定能继续删下去,每次删除这两种字符都会--,但是如果一开始就大于一半,显然不可能,其他的情况必然有解

    注意奇数情况

    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <stdio.h>
    #include <map>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    int casn,n,m,k;
    char s[maxm];
    int vis[1000];
    int main(){
    //#define test
    #ifdef test
    	freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
    #endif
    	scanf("%s",s);
    	n=strlen(s);
    	int flag=1;
    	if(n&1) flag=0;
    	for(int i=0;i<n;i++){
    		vis[s[i]]++;
    	}
    	int cnt=0;
    	for(int i=0;i<1000;i++){
    		cnt=max(vis[i],cnt);
    	}
    	if(cnt<=n/2&&flag) cout<<"YES"<<endl;
    	else cout<<"NO"<<endl;
    
    #ifdef test
    	fclose(stdin);fclose(stdout);system("out.txt");
    #endif
    	return 0;
    }
    

    F

    水题...

    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <stdio.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    int casn,n,m,k;
    int a,b,c;
    
    int main(){
    //#define test
    #ifdef test
    	freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
    #endif
    
    	cin>>a>>b>>c;
    	if(c>b) puts("Stay with this envelope");
    	else puts("Take another envelope");
    
    #ifdef test
    	fclose(stdin);fclose(stdout);system("out.txt");
    #endif
    	return 0;
    }
    

    G

    水题

    直接贪心就好..

    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <stdio.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    
    int casn,n,m,k;
    #define IO ios::sync_with_stdio(false)
    long long a[maxn];
    long long chu[maxn];
    int main(){
    
    IO;
    
    long long ans=0;
    while(cin>>n>>m)
    {
    	for(int i=1;i<=n;i++)
    	cin>>chu[i];
    	n++;
    	memset(a,0,sizeof(a));
    	a[1]=1;
    	int cnt=0;
    	for(int i=2;i<=n;i++)
    	{
    		a[i]=a[i-1]*chu[i-1];
    		cnt=i;
    		if(a[i]>1e11) {
    
    			break;
    		}
      }
      //cout<<a[2]<<endl;
       ans=0;
       int temp=0;
       n=cnt;
    	 for(int i=n;i>=1;i--)
    	 {
    	 	if(a[i]==0) continue;
    			 temp=m/a[i];
    			 ans+=temp;
    			 if(temp>0)
    			 {
    					m-=a[i]*temp;
    			 }
    	 }
    	 cout<<ans<<endl;
    }
    
    
    	return 0;
    }
    

    给一个无向连通图,让你去染色,两点的颜色不同当且仅当两点相邻

    比赛的时候题读错了,必须仔细读才行,幸亏给了sample3...不然得WA一天

    不过一开始说dfs,也确实是可以dfs的...不过是在原图边集的补集上进行dfs,暴力上一种染色就行

    以下是非dfs的n^2算法

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=1e3+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    int casn,n,m,k;
    int g[maxn][maxn];
    int clr[maxn];
    int vis[maxn];
    int main(){
    //#define test
    #ifdef test
    	freopen("in.txt","r",stdin);freopen("out1.txt","w",stdout);
    #endif
    	while(cin>>n>>m>>k){
    		memset(g,0,sizeof g);
    		for(int i=0;i<m;i++){
    			int a,b;
    			scanf("%d%d",&a,&b);
    			g[a][b]=g[b][a]=1;
    		}
    		memset(clr,0,sizeof clr);
    		for(int i=1;i<=n;i++){
    			if(clr[i]) continue;
    			memset(vis,0,sizeof vis);
    			for(int j=1;j<=n;j++){
    				if(i!=j&&g[i][j]) vis[clr[j]]=1;
    			}
    			int tmp=1;
    			while(vis[tmp])tmp++;
    			clr[i]=tmp;
    		}
    		int flag=1;
    		for(int i=1;i<=n&&flag;i++){
    			if(clr[i]>k||!clr[i]) flag=0;
    			for(int j=i+1;j<=n&&flag;j++){
    				if(g[i][j]&&clr[i]==clr[j])flag=0;
    				if(!g[i][j]&&clr[i]!=clr[j]) flag=0;
    			}
    		}
    		if(flag){
    			for(int i=1;i<=n;i++) cout<<clr[i]<<' ';
    			cout<<endl;
    		}else puts("-1");
    	}
    #ifdef test
    	fclose(stdin);fclose(stdout);system("out1.txt");
    #endif
    	return 0;
    }
    

    K

    两个人,n个物品顺序拜访,价值不同,轮流拿东西,只不过A先手,且每次可以任意拿,B后手且每次只能顺序拿剩下的

    每次直接假设A拿走2个,然后每拿2个就把A拿过的最小的那个留给B,维护两人的和就行

    简单来说,A可以选择让B拿走当前这个还是下一个,但A也可以拿后面的,让B既拿这个,也拿下一个

    就用多重集合保存A可以拿的,每次把可以拿的最小的分给B即可

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    int casn,n,m,k;
    multiset<int> vis;
    
    int main(){
    //#define test
    #ifdef test
    	freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
    #endif
    
    	while(cin>>n){
    		vis.clear();
    		long long ans1=0,ans2=0;
    		for(int i=1;i<=n;i++){
    			int t;
    			cin>>t;
    			ans1+=t;
    			vis.insert(t);
    			if(i%2==0){
    				ans1-=*vis.begin();
    				ans2+=*vis.begin();
    				vis.erase(vis.begin());
    			}
    		}
    		cout<<ans1<<' '<<ans2<<endl;
    	}
    
    #ifdef test
    	fclose(stdin);fclose(stdout);system("out.txt");
    #endif
    	return 0;
    }
    

    M

    给你A,B

    要求一个长度为N的数列,为1-N的一个排列,其最长上升子序列长A,最长下降子序列长B,求N的最大值和对应的一种解

    最长可达A*B

    最终子序列由A段长度为B的下降子串构成,每一段下降串的最大值递增

    例如

    5 2

    答案
    10
    2 1 4 3 6 5 8 7 10 9

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    int casn,n,m,k;
    int a1[maxn],a2[maxn];
    
    int main(){
    //#define test
    #ifdef test
    	freopen("in.txt","r",stdin);freopen("out1.txt","w",stdout);
    #endif
    	int a,b;
    	while(cin>>a>>b){
    		cout<<a*b<<endl;
    		n=a*b;
    		int cnt=1;
    		for(int i=1;i<=a;i++){
    			for(int j=i*b;j>b*(i-1);j--){
    				cout<<j<<' ';
    			}
    		}
    		cout<<endl;
    	}
    #ifdef test
    	fclose(stdin);fclose(stdout);system("out1.txt");
    #endif
    	return 0;
    }
    

      

  • 相关阅读:
    深入理解TCP协议及其源代码
    Socket与系统调用深度分析
    构建调试Linux内核网络代码的环境MenuOS系统
    基于java的socket简单聊天编程
    ping命令研究报告
    什么是JMM?
    ssm框架整合,个人学习记录
    Intellij idea兼容 Eclipse 快捷键 (仅个人学习回顾,防止遗忘)
    java基础随记 持续完善中
    win10 安装Ubuntu子系统 整合排坑
  • 原文地址:https://www.cnblogs.com/nervendnig/p/8655767.html
Copyright © 2020-2023  润新知