zoukankan      html  css  js  c++  java
  • 【ACUMTB个人赛】第一周题解

    题目链接:https://vjudge.net/contest/153124

    由于是中文题题意就不放了……

    A题:

    思路:每个点与(0,0)连线的中间点的个数是gcd(a,b),直接暴力会超时,所以换种思路:记录f[i]为gcd=i的个数,f[i]=(n/i)*(m/i)-i的倍数,之后就可以计算啦。

     1 #include <iostream>
     2 #include <cstdio>
     3 
     4 using namespace std;
     5 
     6 typedef long long ll;
     7 
     8 const int maxn=1e5+10;
     9 
    10 ll f[maxn];
    11 
    12 int main(){
    13     ll n,m;
    14     ll ans=0;
    15     cin>>n>>m;
    16     if(n<m) swap(n,m);
    17     for(ll i=n;i>=1;i--){
    18         f[i]=(n/i)*(m/i);
    19         for(ll j=2*i;j<=n;j+=i)
    20             f[i]-=f[j];
    21         ans+=f[i]*(2*i-1);
    22     }
    23     cout<<ans<<endl;
    24     return 0;
    25 }
    View Code

    B题:

    思路:已知图的度序列,判断是否可图化。用havel定理判断,不可图化就输出NO,可图化就输出YES和邻接矩阵,由于此题是Special Judge所以只用输出一种邻接矩阵就行啦。

    havel定理:给定一个非负整数序列{dn},若存在一个无向图使得图中各点的度与此序列一一对应,则称此序列可图化。进一步,若图为简单图,则称此序列可简单图化。把序列排成不增序,即d1>=d2>=……>=dn,则d可简单图化当且仅当d’={d2-1,d3-1,……d(d1+1)-1, d(d1+2),d(d1+3),……dn}可简单图化。简单的说,把d排序后,找出度最大的点(设度为d1),把它与度次大的d1个点之间连边,然后这个点就可以不管了,一直继续这个过程,直到建出完整的图,或出现负度等明显不合理的情况。

    实例:4 3 1 5 4 2 1和4 3 1 4 2 0是否可图化?

    第一组数据,排序后为 5 4 4 3 2 1 1,出度最大的点为5,与度次大的点连边(4 4 3 2 1),之后去掉该点,序列排序后为 3 3 2 1 1 0,以此类推,2 1 1 0 0,0 0 0 0,即该度序列可以图化。

    第二组数据,排序后为4 4 3 2 1 0,连边、去点、排序后为3 2 1 0 0,1 0 0 -1,出现负度,所以该度序列不可图化。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <vector>
     5 #include <cstring>
     6 
     7 using namespace std;
     8 
     9 const int maxn=15;
    10 
    11 typedef pair<int,int> P;
    12 
    13 vector<P> v;
    14 int mp[maxn][maxn];
    15 
    16 int cmp(const P &a,const P &b){
    17     return a.first>b.first;
    18 }
    19 
    20 int n;
    21 
    22 bool judge(){
    23     while(!v.empty()){
    24         sort(v.begin(),v.end(),cmp);
    25         if(v[0].first>=v.size()) return false;
    26         for(int i=1;i<=v[0].first;++i){
    27             --v[i].first;
    28             if(v[i].first<0) return false;
    29             mp[v[0].second][v[i].second]=mp[v[i].second][v[0].second]=1;
    30         }
    31         v.erase(v.begin());
    32     }
    33     return true;
    34 }
    35 
    36 int main(){
    37     ios::sync_with_stdio(false);
    38     cin.tie(0);
    39     int T;
    40     cin>>T;
    41     while(T--){
    42         v.clear();
    43         memset(mp,0,sizeof(mp));
    44         cin>>n;
    45         for(int i=0;i<n;i++){
    46             int tem;cin>>tem;
    47             v.push_back(make_pair(tem,i));
    48         }
    49         bool right=judge();
    50         if(right){
    51             cout<<"YES"<<endl;
    52             for(int i=0;i<n;i++){
    53                 for(int j=0;j<n;j++){
    54                     cout<<mp[i][j]<<" ";
    55                 }
    56                 cout<<endl;
    57             }
    58         }
    59         else cout<<"NO"<<endl;
    60         cout<<endl;
    61     }
    62     return 0;
    63 }
    View Code

    C题:

    思路:优先队列模拟。按优先级从小到大,优先级相等的情况下起始时间从大到小放入优先队列,对于第i个进程,如果i的起始时间i-1的结束时间时间差能够被优先队列中的堆顶进程完全使用(即堆顶进程的持续时间len<=时间差),则该进程的结束时间在这个时间差内,否则len-时间差并重新放回优先队列中。

     1 #include <iostream>
     2 #include <queue>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <cstdio>
     6 
     7 using namespace std;
     8 
     9 typedef pair<int,int> P;
    10 
    11 const int maxn=3e5+10;
    12 const int inf=1e9;
    13 
    14 int start[maxn],slen[maxn],prv[maxn];
    15 
    16 struct node{
    17     int id,len;
    18     bool operator <(const node&a) const{
    19         if(prv[id]==prv[a.id]) return start[id]>start[a.id];
    20         return prv[id]<prv[a.id];
    21     }
    22 };
    23 
    24 P ans[maxn];
    25 
    26 priority_queue<node> q;
    27 
    28 int cmp(const P&a,const P&b){return a.second<b.second;}
    29 
    30 int main(){
    31     int id;
    32     while(scanf("%d",&id)!=EOF){
    33         scanf("%d %d %d",&start[id],&slen[id],&prv[id]);
    34         ans[id].first=id;
    35     }
    36     start[id+1]=inf;
    37     int now=0;
    38     for(int i=1;i<=id+1;i++){
    39         int len=start[i]-now;
    40         while(!q.empty()&&q.top().len<=len){
    41             now+=q.top().len;
    42             ans[q.top().id].second=now;
    43             len-=q.top().len;
    44             q.pop();
    45         }
    46         if(i==id+1) break;
    47         if(!q.empty()&&len){
    48             node tmp=q.top();q.pop();
    49             tmp.len-=len;
    50             q.push(tmp);
    51         }
    52         now=start[i];
    53         q.push((node){i,slen[i]});
    54     }
    55     sort(ans+1,ans+id+1,cmp);
    56     for(int i=1;i<=id;i++){
    57         printf("%d %d
    ",ans[i].first,ans[i].second);
    58     }
    59     return 0;
    60 }
    View Code

    D题:

    思路:LIS(最长上升子串,动态规划)的做法,如果i能够被j(i>j)在限时内抵达,则i可以被j转移。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 using namespace std;
     6 
     7 const int maxn=10005;
     8 
     9 int dp[maxn],x[maxn],y[maxn],t[maxn];
    10 
    11 int main(){
    12     int n,m;
    13     scanf("%d %d",&n,&m);
    14     for(int i=1;i<=m;i++){
    15         scanf("%d %d %d",&t[i],&x[i],&y[i]);
    16     }
    17     dp[1]=1;int ans=1;
    18     for(int i=2;i<=m;i++){
    19         dp[i]=1;
    20         for(int j=1;j<=i-1;j++){
    21             if(abs(x[i]-x[j])+abs(y[i]-y[j])<=t[i]-t[j])dp[i]=max(dp[i],dp[j]+1);
    22         }
    23         ans=max(ans,dp[i]);
    24     }
    25     printf("%d
    ",ans);
    26     return 0;
    27 }
    View Code

    E题:

    思路:由于1e6的数据量,可以从小到大枚举M,判断同余方程Pi-Pj≡Cj-Ci(mod M)是否成立,如果对于每组i,j都不成立,则M为最小的整数解。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 
     5 using namespace std;
     6 
     7 const int maxn=100;
     8 
     9 int exgcd(int a,int b,int &x,int &y){
    10     if(b==0){x=1,y=0;return a;}
    11     int d=exgcd(b,a%b,y,x);
    12     y-=a/b*x;
    13     return d;
    14 }
    15 
    16 int C[maxn],P[maxn],L[maxn];
    17 int n;
    18 
    19 bool solve(int b){
    20     for(int i=1;i<n;i++){
    21         for(int j=i+1;j<=n;j++){
    22             int a=((P[i]-P[j])%b+b)%b,m=((C[j]-C[i])%b+b)%b,x,y,d;
    23             d=exgcd(a,b,x,y);
    24             if(m%d!=0) continue;
    25             m/=d;
    26             int bb=b/d;
    27             int num=(m*x%bb+bb)%bb;
    28             if(num<=min(L[i],L[j])) return false;
    29         }
    30     }
    31     return true;
    32 }
    33 
    34 int main(){
    35     int mx=0;
    36     cin>>n;
    37     for(int i=1;i<=n;i++){
    38         cin>>C[i]>>P[i]>>L[i];
    39         mx=max(C[i],mx);
    40         C[i]--;
    41     }
    42     for(int i=mx;;i++){
    43         if(solve(i)){
    44             cout<<i<<endl;
    45             break;
    46         }
    47     }
    48     return 0;
    49 }
    View Code
  • 相关阅读:
    分析ASP.NET读取XML文件4种方法
    WordPress 主题教程 #4a:Header 模板
    WordPress 主题教程 #4b:Header 模板 2
    倍受好评的美国主机JustHost使用全攻略教程
    单链表的创建、插入、删除、倒置操作
    WordPress 主题教程:从零开始制作 WordPress 主题
    google adsense 设置建议
    PHP:10个不常见却非常有用的PHP函数
    WordPress 主题教程 #2:模板文件和模板
    必须掌握的八个cmd命令行
  • 原文地址:https://www.cnblogs.com/hymscott/p/6517134.html
Copyright © 2011-2022 走看看