2018 Multi-University Training Contest 5

(叹气.jpg)

B.Beautiful Now

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6351

题意:给一串长度为m的数字,k次任意交换其中两个,问可得到的最小数和最大数。

分析:当k>=m-1时直接可以将这m个数排序,直接得到最大或最小。当k<m-1时,枚举每个数所在位置的全排列,与原数位排列比较求出交换次数,在这个过程中求min和max即可。

此外,这个题可以直接暴搜。

#include<bits/stdc++.h>
using namespace std;
const int maxn=15;
char n[maxn];
int k,len,minnum,maxnum;
int c[maxn],p[maxn],q[maxn],p1[maxn];
void init(){
    memset(c,0,sizeof(c));memset(p,0,sizeof(p));memset(p1,0,sizeof(p1));
    len=strlen(n);
    for (int i=0;i<len;i++){
        int xx=n[i]-'0';
        c[i]=xx;p[xx]++;p1[xx]++;
    }    
}
void check(){
    if (c[p[0]]==0) return ;
    for (int i=0;i<len;i++) q[i]=p[i];  //q数组内保存全排列后的位置 
    int sum=0,k1=0;
    for (int i=0;i<len;i++){
        sum=sum*10+c[p[i]];
        if (q[i]!=i){
            for (int j=i+1;j<len;j++){
                if (q[j]==i){
                    swap(q[i],q[j]);
                    k1++;
                    if (k1>k) return ;
                    break;
                }
            } 
        }
    }
    if (k1>k) return ;
    minnum=min(minnum,sum);
    maxnum=max(maxnum,sum);
} 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t;
    cin >> t;
    while (t--){
        cin >> n >> k;
        init();
        if (k>=len-1){
            for (int i=1;i<=9;i++){
                if (p[i]!=0){
                    cout << i;
                    p[i]--;
                    break;
                }
            }
            for (int i=0;i<=9;i++){
                while (p[i]!=0){
                    cout << i;
                    p[i]--;
                }
            }
            cout << " ";
            for (int i=9;i>=0;i--){
                while (p1[i]!=0){
                    cout << i;
                    p1[i]--;
                }
            } 
            cout << endl; 
            continue;
        }
        memset(p,0,sizeof(p));
        for (int i=0;i<len;i++) p[i]=i;
        minnum=2e9,maxnum=-1;
        do{
            check();
        }while(next_permutation(p,p+len));
        cout << minnum << " " << maxnum << endl;
    }
    return 0;
}
hdoj6351

 

E.Everything Has Changed

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6354

题意:求大圆被若干个两两不想交圆切割后外周长。

分析:rt。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const double eps=1e-5;
 4 const double pi=acos(-1.0);
 5 double R;
 6 double _pow(double x){
 7     return x*x;
 8 }
 9 double check(double x,double y,double r){
10     double d=sqrt(_pow(x)+_pow(y));
11     if (d-(r+R)>=eps) return 0.0;  //相离 
12     if (fabs(d+r-R)<=eps) return 2*pi*r;  //内切 
13     if (d+r-R<-eps) return 0.0; //内含 
14     double t1=acos((_pow(r)+_pow(d)-_pow(R))/(2.0*r*d))*2;  //相交 
15     double t2=acos((_pow(R)+_pow(d)-_pow(r))/(2.0*R*d))*2;
16     double s1=t1*r;
17     double s2=t2*R;
18     return s1-s2;
19 }
20 int main(){
21     ios::sync_with_stdio(false);
22     cin.tie(0);cout.tie(0);
23     int t,m;
24     double x,y,r;
25     cin >> t;
26     while (t--){
27         cin >> m >> R;
28         double ans=pi*2.0*R;
29         while (m--){
30             cin >> x >> y >> r;
31             ans=ans+check(x,y,r);
32         }
33         printf("%.10f\n",ans);
34     }
35     return 0;
36 }
hdoj6354

 

G.Glad You Came

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6356

题意:随机数生成,m次操作区间内修改最小值,问最后n个数的异或和。

分析:线段树维护区间最小值即可,区间修改到点,点查询。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10; 
 4 typedef unsigned int ui;
 5 typedef long long ll;
 6 struct point{
 7     int l,r;
 8     int num;
 9 }tree[maxn*4];
10 ui x,y,z;
11 int n,m,X,Y,Z;
12 ui RNG61(){
13     ui w;
14     x=x^(x<<11);
15     x=x^(x>>4);
16     x=x^(x<<5);
17     x=x^(x>>14);
18     w=x^(y^z);x=y;y=z;z=w;
19     return z;
20 }
21 void Build(int root,int l,int r){
22     tree[root].num=0;
23     tree[root].l=l;tree[root].r=r;
24     if (tree[root].l==tree[root].r){
25         return ;
26     }
27     int mid=(tree[root].l+tree[root].r)/2;
28     Build(root<<1,l,mid);
29     Build(root<<1|1,mid+1,r);
30 }
31 void Update(int root,int l,int r,int v){
32     if (tree[root].num>v){
33         return ;
34     }
35     if (tree[root].l==tree[root].r){
36         tree[root].num=v;
37         return ;
38     }
39     int mid=(tree[root].l+tree[root].r)/2;
40     if (l<=mid) Update(root<<1,l,r,v);
41     if (mid<r) Update(root<<1|1,l,r,v);
42     tree[root].num=min(tree[root<<1].num,tree[root<<1|1].num);
43 }
44 int Query(int root,int xx){
45     if (tree[root].l==tree[root].r){
46         return tree[root].num;
47     }
48     int mid=(tree[root].l+tree[root].r)/2;
49     if (xx<=mid) return Query(root<<1,xx);
50     else return Query(root<<1|1,xx);
51 }
52 int main(){
53     ios::sync_with_stdio(false);
54     cin.tie(0);cout.tie(0);
55     int t;
56     cin >> t;
57     while (t--){
58         cin >> n >> m >> X >> Y >> Z;
59         x=X;y=Y;z=Z;
60         Build(1,1,n);
61         for (int i=1;i<=m;i++){
62             int l=RNG61()%n+1,r=RNG61()%n+1,v=RNG61()%(1<<30);
63             if (l>r) swap(l,r);
64             Update(1,l,r,v);
65         }
66         ll ans=0;
67         for (int i=1;i<=n;i++){
68             int xx=Query(1,i);
69             //cout << xx << endl;
70             ans^=1ll*i*xx;
71         }
72         cout << ans << endl;
73     }
74     return 0;
75 } 
hdoj6356

 

posted @ 2018-08-07 20:49  Changer-qyz  阅读(194)  评论(2编辑  收藏  举报