山师闭训赛19_12_15

柳予欣的舔狗行为

Description
某一天柳予欣想去舔爱慕已久却得不到的小姐姐(f译萱)。第一天他去给她偷偷发了一条信息,第二和第三天每天发两条信息,第四到第六天每天发三条信息。。以此类推。可惜小姐姐早就把他给屏蔽了。请问到第K天位置柳予欣一共发了多少条信息?
Input
输入为一个数字n(1<=n<=1e5)
Output
输出柳予欣发的信息条数。
Sample Input
1000
Sample Output
29820

upload successful

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	long k,i;
	bool isequ=false;
	long ans=0;
	cin>>k;
	for(i=1;i<k;i++){
		if(i*(i+1)/2==k){
			isequ=true;
			break;	
		}
		if(i*(i+1)/2>k)break;
	}
	if(isequ){
		long n1=i;
		for(long j=1;j<=n1;j++){
			
			ans+=j*j; 
		} 
	}else{
		long n=i-1;
		for(long j=n*(n+1)/2+1;j<=k;j++){
			ans+=i;
		} 
		for(long j=1;j<=n;j++){
			ans+=j*j; 
		} 
	}
	cout<<ans<<endl;
	return 0;
}
解法二:
#include <iostream>
typedef long long  ll;
const int maxn=1e5+10;
 
ll a[maxn];
using namespace std;
ll n,t,ans;
int main(){
    cin>>n;
    //发消息为2的有两天,发消息为3的有三天,,,,,;i为消息数,j记录发i条消息的天数
    for (int i=1; i<=maxn; i++) {
        for (int j=0; j<i; j++) {
            ans+=i;
            t++;//记录总天数
            if (t>=n) {
                cout<<ans<<endl;
                return 0;
            }
        }
    }
}
柳予欣的女朋友们在分享水果

Description
The hot summer came so quickly that fyx and lmz decided to buy a big and sweet watermelon. They want to cut the watermelon in two parts, and the weight of each part is an even number(偶数).They quickly decide which melon to buy. Do you know if you want to buy this melon?
Input
Only one line contains one integer w (1≤w≤100),units are kilograms.
Output
If it can meet the requirements, you will output “YES”, otherwise output “NO”.
Sample Input
8
Sample Output
YES

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include<iostream>
using namespace std;
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	int w;
	cin>>w;
	for(int i=1;i<w;i++){
//	因为不能一下全取w,所以从1开始到w(开) 
		if((w-i)%2==0&&i%2==0){
			cout<<"YES"<<endl;
			return 0;
		}
	}
	cout<<"NO"<<endl; 
	return 0;
}
解法2
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long  ll;
int main(){
    int n;
    cin>>n;
    if (n%2==0) {//上面合在一起不就是n能不能余2嘛
        if (n==2) cout<<"NO"<<endl;
        else cout<<"YES"<<endl;
    }
    else cout<<"NO"<<endl;
}
解法三:
#include <bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	scanf("%d",&n);
	if(n==2||(n&1))
	printf("NO");
	else
	printf("YES"); 
}
柳予欣和她女朋友的购物计划

Description
一天,柳予欣和她的一个女朋友fyx去买包包。可惜的是柳予欣现在手里只有两种面值的钱a,b(a,b彼此互为素数,即这两个整数的公因数只有1),数量无限大。为了不让自己没面子,他想知道无法准确支付的物品中(就是不通过找零,用非负数个钱a与钱b不能凑成的价格中),最贵的价值是多少金币?
Input
输入数据仅一行,包含两个正整数,它们之间用一个空格隔开,分别表示a,b的面值。(a和b均大于1,且均小于1,000,000,000)
Output
输出所求数即可。
Sample Input
3 7
Sample Output
11

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
错误思路
#include<bits/stdc++.h>
using namespace std;

const int maxn=1e8;
const int max1=1e7;
int prime[max1];
bool noPrime[max1];


//本来以为是大于这两个数的最大中的一个数的后一个素数,其实
//要读懂题意之后发现不是这样的 
int eulerSieve(long long n){
	int num=1;
	memset(prime,0,sizeof(prime));
	memset(noPrime,false,sizeof(noPrime));
	noPrime[0]=noPrime[1]=true;
	for(long long i=2;i<=n;i++){
		//从1开始存素数 
		if(noPrime[i]==false)prime[num++]=i;
		for(int j=1;j<num&&i*prime[j]<=n;j++){
			noPrime[i*prime[j]]=true;
			if(i%prime[j]==0)break;
		}
	} 
	return num-1;
} 

int main(){
	long long a,b,n;
	long long i;
	cin>>a>>b;
	n=max(a,b);
eulerSieve(maxn);
	for(i=0;i<n;i++)
	{
		if(prime[i]==n)break;
	}
	cout<<prime[i+1];
} 

ac代码://打表找规律,不要没有根据的乱猜
#include <iostream>
using namespace std;
typedef long long  ll;
int main(){
    ll a,b;
    cin>>a>>b;
    cout<<(ll)a*b-a-b<<endl;
}
FFFFFunctions

upload successful

Sample Input
2
3 5
2 1
Sample Output
1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
//const int maxn=1e6+10;
int a[1000005];
int p[1000005];
//inline int fun(int a,int b){
//		int tmp;
//		while(b!=0){
//			tmp=a;
//			a=b;
//			b=abs(tmp-b);
//		}
//		return a;
//}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	int n,ans;
	//这道题因为没看懂题意,以为要输入组数,所以错了 
	while(cin>>n){
		if(n==0)continue;
		for(int i=1;i<=n;i++)cin>>a[i];
		for(int i=1;i<=n;i++)cin>>p[i];
		//ans=fun(a[p[1]],a[p[2]]);
		ans=__gcd(a[p[1]],a[p[2]]);
		for(int i=3;i<=n;i++){
			//ans=fun(ans,a[p[i]]); 
			ans=__gcd(ans,a[p[i]]);
		}
		cout<<ans<<endl;
	}
}
方法2
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
while(scanf("%d",&n)!=EOF){
    if(n==0) continue;
    long long int t;
    long long int a=0;
    for(int i=1;i<=n;i++){
       cin>>t;
       a=__gcd(t,a);
    }
    for(int z=1;z<=n;z++){
        int y;
        cin>>y;
      }
     cout<<a<<endl;
}
return 0;
}
1586.柳予欣不想挂科

题目链接:http://sdnuoj.rainng.com/problem/show/1586
Description
期末考试要到了,学习不好的柳予欣要挂科了。这时他的一个女朋友lmz过来帮他补习科目。一共有n门科目,柳予欣对于每门都有目标成绩mi。lmz每次可以让他任意一个连续区间的科目的目标成绩提升一(n门科目初始状态成绩全为0)。因为柳予欣太懒,他只想把每一门补习到他想要的成绩,高了不行低了也不行。请问最少要让lmz帮他补习多少次?
Input
第一行一个数表示n (n <= 100000)
第二行n个数表示每个mi即每个科目的目标成绩。
Output
输出最小需要的帮助次数
Sample Input
5
2 3 4 1 2
Sample Output
5
Hint
对于样例来说,最少需要五次,每次补习科目区间为:
[1,5] [1,3] [2,3] [3,3] [5,5]
即可使所有科目的成绩提高到目标成绩了
思路:
补题的时候补着补着就笑啦~ 为啥这道水题我没看到呢~涨姿势。
找规律,如果一个数在这个序列中下降了,分成块,就是找递增序列之间的差值。看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
const int maxn=1e5+10;
typedef long long  ll;
using namespace std;
int n;
int a[maxn];
ll ans;
int main(){
    cin>>n;
    for (int i=1; i<=n; i++) cin>>a[i];
    ans=a[1];
    for (int i=2; i<=n;i++)
        if (a[i]>a[i-1]) ans+=a[i]-a[i-1];
    cout<<ans<<endl;
}
解法二:
#include <bits/stdc++.h>
using namespace std;
const int N=200005;
long long maxn=0,re=0,a[N],ans=0,now=0;
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	scanf("%lld",&a[i]);
	now=a[1];
	for(int i=2;i<=n-1;i++)
	{//不是很懂????
		now=max(now,a[i]);
		if(a[i]<a[i-1]&&a[i]<=a[i+1])
		ans+=now,ans-=a[i],now=0;
	}
	now=max(now,a[n]); 
	ans+=now;
	printf("%lld",ans);
}
斐波那锲问题

中文名
斐波那契数列 、黄金分割数列、兔子数列 性质
表达式
F[n]=F[n-1]+F[n-2]( n>=3,F[1]=1,F[2]=1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
斐波那契数列规律总结

   随着数列项数的增加,前一项与后一项之比越来越逼近黄金分割的数值0.6180339887..
   从第二项开始,每个奇数项的平方都比前后两项之积多1,每个偶数项的平方都比前后两项之积少1。(注:奇数项和偶数项是指项数的奇偶,而并不是指数列的数字本身的奇偶,比如第五项的平方比前后两项之积多1,第四项的平方比前后两项之积少1)
   斐波那契数列的第n项同时也代表了集合{1,2,…,n}中所有不包含相邻正整数的子集个数。
   f(0)+f(1)+f(2)+…+f(n)=f(n+2)-1
   f(1)+f(3)+f(5)+…+f(2n-1)=f(2n)
   f(2)+f(4)+f(6)+…+f(2n) =f(2n+1)-1
   [f(0)]^2+[f(1)]^2+…+[f(n)]^2=f(n)·f(n+1)
   f(0)-f(1)+f(2)-…+(-1)^n·f(n)=(-1)^n·[f(n+1)-f(n)]+1
   f(m+n)=f(m-1)·f(n-1)+f(m)·f(n) (利用这一点,可以用程序编出时间复杂度仅为O(log n)的程序。)
   [f(n)]^2=(-1)^(n-1)+f(n-1)·f(n+1)
   f(2n-1)=[f(n)]^2-[f(n-2)]^2
   3f(n)=f(n+2)+f(n-2)
   f(2n-2m-2)[f(2n)+f(2n+2)]=f(2m+2)+f(4n-2m) [ n〉m≥-1,且n≥1]斐波那契数列
   通向公式 an=(1/√5)*[(1+√5/2)^n-(1-√5/2)^n](n=1,2,3…..)
   gcd(fib(n),fib(m))=fib(gcd(n,m))
   如果fib(k)能被x整除,则fib(k*i)都可以被x整除。
   数列中相邻两项的前项比后项的极限(-1+√5)/2
   求递推公式a(1)=1,a(n+1)=1+1/a(n)的通项公式 a(n)=fib(n+1)/fib(n)

可用矩阵快速幂求

upload successful
upload successful

  • 求斐波那锲数列的集中方法???
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
因为任意一个数都可以用斐波那锲数来叠加求得,所以直接从后往前,直接减掉,直到减为0就好了。其实比赛的时候想到了这个解法,一想,任意一个数是可以用斐波那锲数表示吗,不确定是不是,就没敢写。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
typedef long long ll;
const ll maxn=5e18;
using namespace std;
 
ll a[1000],n;
int t;
int main() {
    a[1]=1;a[2]=2;
    for (int i=3;; i++)
    {
        a[i]=a[i-1]+a[i-2];
        if (a[i]>maxn) {
            t=i-1;
            break;
        }
    }// 找出斐波那契数列 个数为t个
     
    while (~scanf("%lld",&n)) {
        if (!n) continue;
        else {
            for (int i=t; i>0; i--) {  //从后向前找
                if (n>=a[i]) {       //n在不小于0的情况下能减去就减去。
                    n-=a[i];
                    if (n) printf("%lld ",a[i]);
                    else {
                        printf("%lld\n",a[i]);  //注意格式问题
                        break;
                    }
                }
            }
        }
    }
}

解法二:
#include <bits/stdc++.h>
using namespace std;
long long a[1005];
int main()
{
	a[1]=1,a[2]=1;
	for(int i=3;i<=92;i++)//因为long long范围中斐波那锲数为92个
	a[i]=a[i-1]+a[i-2];
	long long n;
	while(~scanf("%lld",&n))
	{
		if(n==0)
		continue;
		while(n)
		{
			int pos,f=0;
			for(int i=1;i<=92;i++)
			{
				pos=i;
				if(a[i]>=n)
				{
					if(a[i]>n)
					f=1; 
					break;
				}
			}
			if(f)
			{
				n-=a[pos-1];
				printf("%lld%c",a[pos-1],n?' ':'\n');
			}
			else
			{
				n-=a[pos];
				printf("%lld%c",a[pos],n?' ':'\n');
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值