西安邮电大学第五届ACM-ICPC校赛(同步赛)

比赛入口

文章目录

  • B-烦人的依赖(字典序的拓扑排序)- 超时
  • E - 无敌阿姨(模拟)
  • G- 校车(差分+离散化)
  • H-中位数因子(思维)*

B-烦人的依赖(字典序的拓扑排序)- 超时

有字典序的拓扑排序,但是因为容易超时所以可以将字符串映射成数字来操作,还有就是接收字符串后要排序后映射,不然也会超时(我也不知道这是什么玄学)

#include 
#include  
#include 
#include 
#include 
#include 
#include 
#include 
typedef long long ll ; 
using namespace std ;
const int N = 3e4+10 ; 
const ll mod=1e9+7 ;
string str[N] ; 
vector<int> v[N] ; 
map<string,int> p ; 
int in[N] ,ans[N],n,m,pos;  
void tuopu(){
     
	priority_queue<int,vector<int>,greater<int> > q ; 
	for(int i=1 ; i<=n ; ++i)
		if(in[i]==0)	q.push(i) ; 
	int cnt=0 ; 
	while(!q.empty()){
     
		int x=q.top() ; q.pop() ; 
		ans[pos++]=x ; ++cnt ; 
		for(int i=0 ; i<v[x].size() ; ++i){
     
			int y=v[x][i] ;    -- in[y] ; 
			if(in[y]==0)	q.push(y) ; 
		}
	}
	if(cnt==n){
     
		for(int i=0 ; i<pos ; ++i)	cout<<str[ans[i]]<<endl ; 
	}
	else	cout<<"Impossible"<<endl ; 
}
int main(){
     
	ios::sync_with_stdio(false);
	int t; cin>>t ; 
	for(int cnt=1 ; cnt<=t ; ++cnt){
     
		cin>>n>>m;
		pos=0 ; 
		p.erase(p.begin(),p.end()) ; 
		for(int i=1 ; i<=n ; ++i)    cin>>str[i] ; 
        sort(str+1,str+1+n) ; //要先排序,不然会超时(不知道这是什么玄学)
        for(int i=1 ; i<=n ; ++i){
     
            v[i].clear() ; 
			in[i]=0 , p[str[i]]=i ;  
		}
		for(int i=0 ; i<m ;++i){
     
			string a,b; cin>>a>>b ; 
			++in[p[b]]  ; 
			v[p[a]].push_back(p[b]) ; 
		}
		cout<<"Case #"<<cnt<<":"<<endl ;  
		tuopu(); 
	}
	return 0 ; 
}
	

E - 无敌阿姨(模拟)

根据题意模拟一下,虽然是模拟题但是细节还是要注意一下。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
typedef long long ll ;
using namespace std ;
const int N = 1e2+10 ;
const ll mod=1e9+7 ;
int a[N] ;
int main(){
     
    int t ; scanf("%d",&t) ;
    /*4 5 1
    1 1 2 4*/
    while(t--){
     
        int n,m,k; scanf("%d%d%d",&n,&m,&k) ;
        for(int i=1 ; i<=n ; ++i)    scanf("%d",&a[i]) ;
        int cnt=0 , res=m ;
        for(int i=1 ; i<=n ; ++i){
     
            if(res-a[i]>=0)      res-=a[i] ;
            else{
     
                a[i]-=res , res=m , ++cnt ,--i ;//没有收完所以要--i
                continue ;
            }
            if(i!=n){
     
                if(res>=k)   res-=k ;    //上楼
                else    res=m ,++cnt ;  //不上楼
            }
        }
        printf ("%d\n",cnt+1) ;
    }
    return 0 ;
}

G- 校车(差分+离散化)

因为站点的数太大需要离散一下,然后用差分标记每个站坐的人,最后差分数组最大值就是需要安排座位的数目,unique后就是站点数

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
typedef long long ll ;
using namespace std ;
const int N = 1e5+10 ;
const ll mod=1e9+7 ;
int a[N],b[N],c[2*N] ;
vector<int> v ; 
int main(){
     
    int t; scanf("%d",&t) ;
    while(t--){
     
        v.clear() ;
        int n; scanf("%d",&n) ;
        for(int i=1 ; i<=n ; ++i){
     
            scanf("%d%d",&a[i],&b[i]) ;
            v.push_back(a[i]) ;
            v.push_back(b[i]) ; 
        }
        sort(v.begin(),v.end()) ;
        int k = unique(v.begin(),v.end())-v.begin();
        int cnt =0 ;
        memset(c,0,sizeof(c)) ;
        for(int i=1 ; i<=n ; ++i){
     
            a[i] = lower_bound(v.begin(),v.begin()+k,a[i])-v.begin()+1 ;
            b[i] = lower_bound(v.begin(),v.begin()+k,b[i])-v.begin()+1 ;
            ++c[a[i]] , --c[b[i]] ;
        }
        for(int i=1 ; i<=k ; ++i){
     
            c[i] += c[i-1] ;
            cnt=max(cnt,c[i]) ;
        }
        printf ("%d %d\n",k,cnt) ;
    }
    return 0 ;
}

H-中位数因子(思维)*

先统计一下每个数的因子数目,然后在第二层枚举的时候,如果找到中位数就可以计算 , (a[j]+1)/2 == b[j] (因子中数刚好是当前枚举的因子)。

#include 
#include  
#include 
#include 
#include 
#include 
#include 
#include 
typedef long long ll ; 
using namespace std ;
const int N = 1e6+10 ; 
const ll mod=1e9+7 ;
ll a[N],b[N],s[N] ;  
int main(){
     
	for(int i=1 ; i<=1e6 ; ++i){
     
		for(int j=i ; j<=1e6 ; j+=i)
			++a[j] ; //统计每个数的因子个数 
	}
	for(int i=1 ; i<=1e6 ; ++i){
     
		for(int j=i ; j<=1e6 ; j+=i){
     
			++b[j] ; 
			//i为j的因子的中位数,中位数求平均值
			if( (a[j]+1)/2 == b[j])	s[j]=(i+j/i)/2 ; 
		}
	} 
	for(int i=1 ; i<=1e6 ; ++i)		s[i]=(s[i]+s[i-1])%mod ; 
	int t; scanf("%d",&t) ;
	while(t--){
     
		ll n; scanf("%lld",&n) ; 
		printf ("%lld\n",s[n]) ;  
	}
	return 0 ; 
}
	

你可能感兴趣的:(训练赛)