弱鸡儿长乐爆零旅Day5

T1圆圈舞蹈

【问题描述】

    熊大妈的奶牛在时针的带领下,围成了一个圈跳舞。由于没有严格的教育,奶牛们之间的间隔不一致。

    奶牛想知道两只最远的奶牛到底隔了多远。奶牛A到B的距离为A顺时针走和逆时针走,到达B的较短路程。告诉你相邻个奶牛间的距离,请你告诉奶牛两只最远的奶牛到底隔了多远。

【输入格式】

    第一行一个整数N,表示有N只奶牛。(2<=N<=100000)

    接下来2~N+1行,第I行有一个数,表示第I-1头奶牛顺时针到第I头奶牛的距离。(1<=距离<=maxlongint,距离和<=maxlongint)

    第N+1行的数表示第N头奶牛顺时针到第1头奶牛的距离。

【输出格式】

    一行,表示最大距离。

【输入样例】Circle.in

    5
    1
    2
    3
    4
    5

【输出样例】Circle.out

    7

样例解析】

    所有奶牛I到J之间的距离和到达方式(顺为顺时针,逆为逆时针)如下

I\J

1

2

3

4

5

1

0

1(顺)

3(顺)

6(顺)

5(逆)

2

1(逆)

0

2(顺)

5(顺)

6(逆)

3

3(逆)

2(逆)

0

3(顺)

7(顺)

4

6(逆)

5(逆)

3(逆)

0

4(顺)

5

5(顺)

6(顺)

7(逆)

4(逆)

0

    所以,最远的两头奶牛为3到5,距离是7。

 

(我也不是很懂为什么我写的n^2的算法过了qaq)

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int a[100010];
 5 int summ[100010];
 6 int ans=-1;
 7 int mid,n;
 8 inline int read()
 9 {
10     int f=0;
11     char ch=getchar();
12     while(ch>'9' || ch<'0')
13         ch=getchar();
14     while(ch>='0' && ch<='9'){
15         f=f*10+ch-'0';
16         ch=getchar();
17     }
18     return f;
19 }
20 
21 int main()
22 {
23     freopen("circle.in","r",stdin);
24     freopen("circle.out","w",stdout);
25     scanf("%d",&n);
26     for(int i=1;i<=n;i++){
27         a[i]=read();
28         summ[i]=summ[i-1]+a[i];
29     }
30     int mid=summ[n]/2;
31     for(int i=1;i<=n;i++){
32         for(int j=i+1;j<=n;j++){
33             ans=max(ans,min(summ[j]-summ[i],summ[n]-summ[j]+summ[i]));
34             if(ans==mid)break;
35         }
36     }
37     printf("%d",ans);
38     return 0;
39 } 
 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 const int MAXN = 100005;
 8 int ans, a[MAXN], b[MAXN], n, i, j, k, tot, t;
 9 int main()
10 {
11     freopen("circle.in", "r", stdin);
12     freopen("circle.out", "w", stdout);
13     cin >> n;
14     for(i = 1; i <= n; i ++)
15         scanf("%d", &a[i]);
16     for(i = 1; i <= n; i ++)
17         tot += a[i];
18     j = 2;
19     t = a[1];
20     for(i = 1; i <= n; i ++)
21     {
22         while (min(t, tot - t) <= min(t + a[j], tot - t - a[j]) && j < n) j ++, t += a[j - 1];
23         ans = max(ans, min(t, tot - t));
24         t -= a[i];
25     }
26     cout << ans << endl;
27     fclose(stdin); fclose(stdout);
28 }

标程如上 是O(n)算法

因为最远距离一定是接近mid值的 因此我们可以寻找不超过mid的最大值

 

T2小麦亩产一千八

【问题描述】

     “有了金坷垃,肥料一袋能顶两袋撒,小麦亩产一千八,吸收两米下的氮磷钾……”,话说HYSBZ(Hengyang School for Boys & Zy)学识渊博孩纸们一讲到粮食,都会想起印度那个著名的故事:国王要在第一个格子里放入一粒小麦,接下来的格子放入前面一个格子的两倍的小麦。这样所需小麦总数是巨大的,哪是不用金坷垃就能完成的任务?不过为了减轻国王的任务,那个下棋获胜的宰相换了一个要求:“我只需要你在棋盘外放一粒小麦,可以将其理解为第0个格子,然后你需要在第一个格子里放入若干小麦,之后每一个格子放入前两个格子的小麦数之和的小麦,并且要满足第a个格子放x粒小麦,第b个格子放……”说到这,宰相突然发现自己说的满足第a个格子放x粒小麦的情况可能不存在……欺君可是大罪啊!国王看到宰相迟迟不说,自己也烦了!我自己来算!于是国王拜托你,让你算出第b个格子应该放几粒小麦。当然,就算答案不存在,你也是要告诉国王的。

 

【输入格式】kela.in

    该题有多组数据,请读到文件末结束。

对于每一组数据仅一行,3个正整数a,x,b,分别表示第a个格子放了x粒小麦,以及你所需要计算的是第b个格子的小麦数量。

 

【输出格式】kela.out

  对于每一次询问,仅1个整数,为第b个格子的小麦数量,若宰相说的情况不存在,那么请输出-1。

 

样例输入

样例输出

1 1 2
3 5 4
3 4 6
12 17801 19

2

8

-1

516847

【样例解释】

    对于样例二,f[1]=2时,能够满足f[3]=5,因此宰相没有撒谎,此时第5个格子的小麦数应为f[4]=f[2]+f[3]=3+5=8.

数据范围与约定

    对于50%的数据:如果答案存在,那么p<=50

    对于100%的数据:1<=数据组数<=10000,1<=a,b<=20, 数据保证如果答案存在,那么1<=p<=1000000.(注:p是第一格放置的小麦数)。

只是第一个放的小麦数在int范围里 后面的未必

所以 要开longlongTvT

全部加longlong就ac了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define ass cout<<"ass"
 5 using namespace std;
 6 //qaq是第二位上的数 
 7 //第n位上的数是fb[n-1]*qaq+fb[n-2]
 8 long long qaq;
 9 long long x,a,b;
10 long long fb[30]={0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393};
11 int main()
12 {
13 
14     while(scanf("%lld%lld%lld",&a,&x,&b)!=EOF)
15     {
16         if((x-fb[a-1])%fb[a]){
17             printf("-1\n");
18             continue;
19         }
20         qaq=(x-fb[a-1])/fb[a];
21         printf("%lld\n",fb[b]*qaq+fb[b-1]);
22     }
23     return 0;
24 }

 

T2好元素

【问题描述】

小A一直认为,如果在一个由N个整数组成的数列{An}中,存在以下情况:

Am+An+Ap = Ai (1 <= m, n, p < i <= N ,  m,n,p可以相同),那么Ai就是一个好元素。

现在小A有一个数列,请你计算数列中好元素的数目。

 

【输入格式】

第一行只有一个正整数N,意义如上。

第二行包含N个整数,表示数列{An}。

【输出格式】

输出一个整数,表示这个数列中好元素的个数。

 

【输入样例】

Sample1

2

1 3

Sample2

6

1 2 3 5 7 10

Sample3

3

-1 2 0

 

【输出样例】

Sample1

1

Sample2

4

Sample3

1

 

【数据范围】

对于10%的数据1<=N<=10

对于40%的数据1<=N<=500 -10^5<=Ai<=10^5

对于70%的数据1<=N<=5000 -10^6<=Ai<=10^6

对于100%的数据1<=N<=5000 -10^9<=Ai<=10^9

哈希表

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int qaq=1e8+5;
 6 const int mod=4194303;
 7 int a[5010];
 8 int ans;
 9 inline int read()
10 {
11     int f=0;
12     int temp=1;
13     char ch=getchar();
14     while(ch>'9' || ch<'0'){
15         if(ch=='-')temp=-1;ch=getchar();
16     }    
17     while(ch>='0' && ch<='9'){
18         f=f*10+ch-'0';
19         ch=getchar();
20     }
21     return temp*f;
22 }
23 int head[mod+10],ver[qaq],nxt[qaq],tot;
24 void add(int x){
25     int y=x&mod;//负数别%
26     ver[++tot]=x;
27     nxt[tot]=head[y];
28     head[y]=tot;
29 }
30 bool query(int x){
31     int y=x&mod;
32     for(int i=head[y];i;i=nxt[i]){
33         if(x==ver[i])return true;
34     }
35     return false;
36 }
37 int main(){
38     int n;
39     scanf("%d",&n);
40     for(int i=1;i<=n;i++)
41         a[i]=read();
42         
43                 
44     for(int i=1;i<=n;i++){
45         for(int j=1;j<i;j++)
46             if(query(a[i]-a[j])){
47                 ans++;
48                 break;
49             }
50         for(int k=1;k<=i;k++){
51             add(a[i]+a[k]);
52         }            
53     }
54     printf("%d",ans);
55     return 0;
56 }

 

posted @ 2019-07-26 22:11  Markill  阅读(161)  评论(0编辑  收藏  举报