UPC2018组队训练赛第十二场

题目来自2018黑龙江省赛


A题:A Count Task

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 char str[100050];
 4 typedef long long ll;
 5 int main()
 6 {
 7     int t;
 8     scanf("%d",&t);
 9     while(t--)
10     {
11         scanf("%s",str);
12         int len=strlen(str);
13         ll ans=1;
14         int cnt=1;
15         for(int i=1;i<len;i++)
16         {
17             if(str[i]==str[i-1])
18             {
19                 cnt++;
20                 ans+=(ll)cnt;
21             }
22             else
23             {
24                 cnt=1;
25                 ans+=(ll)cnt;
26             }
27         }
28         printf("%lld
",ans);
29     }
30     return 0;
31 }
View Code

B题: A Math Problem

训练赛时想到的思路是 求前n个奇数的乘积,但是n是1e18的范围,所以就不知道怎么写

待更新


C题:A Path Plan

结论题 Lindström–Gessel–Viennot引理  可参考https://blog.csdn.net/ftx456789/article/details/81132126

有两个人分别给出他们的起点和终点,在他们从起点到终点的过程中(只能往右或者下走),求他们不交叉的走法有多少种

首先知道一个人从(0,y)走到(x,0)的方法是C(x+y,x)

设第一个人的起点是(0,y1)终点是(x1,0),第二个人的起点是(0,y2)终点是(x2,0),结果就是C(x1+y1,x1)*C(x2+y2,x2)-C(x1+y2,x1)*C(x2+y1,x2)

我们还要注意,如果(x1-x2)*(y1-y2)<0,那么答案就是0

还有就是貌似,不能定义y1这个变量名,我提交上去编译错误,然后改成其他的变量名就过了。。

之前发现不能定义y1是因为会与cmath头文件的y1重名。但这次没有cmath头文件,并且在本地编译器都通过了,提交上去就不能编译。。。不知道为什么 。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 
 5 using namespace std;
 6 const int mod=1e9+7;
 7 const int N=200005;
 8 typedef long long ll;
 9 ll fac[N],inv[N];
10 ll qpow(ll x,ll y)
11 {
12     ll ret=1;
13     while(y)
14     {
15         if(y&1) ret=(ret*x)%mod;
16         x=x*x%mod;
17         y>>=1;
18     }
19     return ret;
20 }
21 void init()
22 {
23     fac[0]=1;
24     for(ll i=1;i<=N+1;i++)  fac[i]=(fac[i-1]*i)%mod;
25     inv[N+1]=qpow(fac[N+1],mod-2);
26     for(ll i=N;i>=0;i--)    inv[i]=(inv[i+1]*(i+1))%mod;
27 }
28 ll C(ll x,ll y)
29 {
30     if(!x&&!y)  return 1;
31     if(x<y) return 0;
32     return fac[x]*inv[y]%mod*inv[x-y]%mod;
33 }
34 ll t,xx1,xx2,yy1,yy2;
35 int main()
36 {
37     init();
38     scanf("%lld",&t);
39     while(t--)
40     {
41         scanf("%lld%lld%lld%lld",&xx1,&xx2,&yy1,&yy2);
42         if((xx1-xx2)*(yy1-yy2)<0)   {printf("0
");continue;}
43         ll ans=((C(xx1+yy1,xx1)%mod*C(xx2+yy2,xx2)%mod-C(xx1+yy2,xx1)%mod*C(yy1+xx2,xx2)%mod)%mod+mod)%mod;
44         printf("%lld
",ans);
45     }
46     return 0;
47 }
View Code

  

D题:A Sequence Game

有一个序列,有m次询问,每次询问一个区间,问在这个区间里从这个区间的最小值到最大值之间的值是否都出现

待更新


E题:A Hard Allocation

水题

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3  
 4 int main()
 5 {
 6     int t,n,m;
 7     scanf("%d",&t);
 8     while(t--)
 9     {
10         scanf("%d %d",&n,&m);
11         if(n%m==0)
12         {
13             printf("0
");
14         }
15         else
16         {
17             printf("1
");
18         }
19     }
20     return 0;
21 }
View Code

F题:Similar Strings

待更新


G题:Flower

待更新


H题:Overflow

在木桶里原来有V体积的水 ,放入n个正方体的木块后,水的高度是多少

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct node
 4 {
 5     double l,p;
 6 } cube[10050];
 7 double s,h,v,h1;
 8 double fun(double len,double ph)
 9 {
10     if(len*len*len*ph<len)
11     {
12         return len*len*len*ph;
13     }
14     return len;
15 }
16 int main()
17 {
18     int t,n;
19     scanf("%d",&t);
20     while(t--)
21     {
22         scanf("%d",&n);
23         for(int i=1; i<=n; i++)
24         {
25             scanf("%lf %lf",&cube[i].l,&cube[i].p);
26         }
27         scanf("%lf %lf %lf",&s,&h,&v);
28         h1=v/s;
29 //        printf("%.2lf
",h1);
30         for(int i=1; i<=n; i++)
31         {
32             double h2;
33             if(cube[i].p>=1)
34             {
35                 h2=cube[i].l;
36             }
37             else
38             {
39                 h2=cube[i].l*cube[i].l*cube[i].l*cube[i].p;
40             }
41             double v2=h2*cube[i].l*cube[i].l;
42             h1+=v2/s;
43 //            printf("%.2lf
",h1);
44         }
45         if(h1>h)
46         {
47             printf("%.2lf
",h);
48         }
49         else
50         {
51             printf("%.2lf
",h1);
52         }
53     }
54     return 0;
55 }
View Code

I题:Binary

待更新


 J题:The puzzle

给你一个乱序的序列,问将它变成从小到大的序列要多少步,题目要求交换的两个元素是任意的

一开始没有看到交换的元素是任意的,于是写了逆序对结果错了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int a[100050];
 4 typedef long long ll;
 5 ll ans;
 6 int main()
 7 {
 8     //freopen("in.txt","r",stdin);
 9     int t,n;
10     scanf("%d",&t);
11     while(t--)
12     {
13         ans=0;
14         scanf("%d",&n);
15         for(int i=1;i<=n;i++)
16         {
17             scanf("%d",&a[i]);
18         }
19         for(int i=1;i<=n;i++)
20         {
21             while(a[i]!=i)
22             {
23                 swap(a[i],a[a[i]]);
24                 ans++;
25             }
26         }
27         printf("%lld
",ans);
28     }
29     return 0;
30 }
31  
View Code
如有错误,请指正,感谢!
原文地址:https://www.cnblogs.com/scott527407973/p/9590576.html