week5:

私人笑声:

知识点一:EOF

在while循环中以EOF作为文件结束标志,这种以EOF作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的 ASCII 代码值的形式存放。我们知道,ASCII代码值的范围是0~255,不可能出现-1,因此可以用EOF作为文件结束标志。

如果scanf()函数全部正常读取,它就返回几。

while((scanf"%d,%d",&m,&n)==2)

while((scanf"%d,%d",&m,&n)!=EOF)

输入空格的几种方法:

1,string a;

getline(cin.a);

2,    char a[N];

cin.getline(a,num);

3.gets一般不能用

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10 ;
int n , v[N] ;
char s[N];
string o;
string ans;
int main(){
	while((scanf("%s",&s))!=EOF){
		int u=strlen(s);
	
			for(int i=0;i<u;i++){
				if(s[i]=='.'){
					cout<<s[i]<<"xixixixi";
				}
				cout<<s[i];
			}
		
		cout<<" ";
	
		
	}
	return 0;
}

该加训啦:

位运算:1&(与):只有两位数字都是1,结果才为1,否则为0;

2 |(或):有至少一个1,结果就为1;

2 ^ (异或):相同位数字相同则为0,不同就为1;

3~(取反):略;

4 << (左移);<<<(无符号左移)

5 >>(右移):>>>(无符号右移)

常用公式:a^0=a  (任何数异或0是它本身)

a^a=0 (两个相同的数异或和为0)

a^(b^c)=(a^b)^c;(异或和满足结合律)

a^b=b^a;(异或和满足交换律)

a | 0=a(一个数或0还是这个数)

a | ~ a =1;

a | a = a;

a | ( b | c )=( a | b ) | c;

a | b = b | a;

a & 0=0;

a&~a=0;

a&a=a  

一样满足交换律和结合律;

列出4种情况,观察可知(a&b)^(a|b)=a^b;

用前缀异或和记忆化储存

因为r^r=0;

a^0=a;

所以可以让最终的前缀和 ^ (l-1)之前的前缀和,(l-1)就全为0了,就可以得到最终的答案;

代码:

#include <bits/stdc++.h>
using namespace  std;
#define  PII pair<int,int>
#define int long long
int x[200005],sum[200005];
signed main(){
	int n,m;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>x[i];
	}
	for(int i=1;i<=n;i++){
		sum[i]=sum[i-1]^x[i];
	}
	cin>>m;
	for(int i=0;i<m;i++){
		int l,r;
		cin>>l>>r;
		cout<<(sum[r]^sum[l-1])<<endl;
	}
	return 0;
}

奶茶袋收集

要找出最小的极差和:

一组里面的最大值-最小值=相邻两数的差值之和

所以计算所有相邻两数的差值之和

因为要分成m段,就有m-1个差值不在极差和里;

减掉即可;但要求极差和最小,所以对每个差值排序,

依次减去最大的差值就好

#include <bits/stdc++.h>
using namespace std;
#define int long long
int a[100005],sum=0;
int b[100005];
signed main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
    sort(a+1,a+1+n);
	for(int i=2;i<=n;i++){
		int x;
		b[i-1]=a[i]-a[i-1];
		sum+=b[i-1];
	}
	sort(b,b+n);
	int cha=0;
	for(int i=n-1,k=0;k<m-1;i--,k++){
		cha+=b[i];
	}
	int ans=sum-cha;
	cout<<ans;
	return 0;
}

基于文化课的算法学习:

此题注意find_first/last_of的用法:(错用成查找第一次出现此字符的位置)

find找不到时返回-1!不是0!;

转载:

C++ find_first_of-CSDN博客

#include <bits/stdc++.h>
using namespace std;
string a,b,c="zxz",d;
	string q,aa="main";
	string bb="return";
	int n,k,x;
	int mm,ee;
int main(){
	cin>>n;
	cin>>b>>a;
	d=a;
    if(a.find(aa)==-1||a.find(bb)==-1){
        cout<<"wrong"<<endl;
			 return 0;
    }
    else{
        mm=a.find(aa);
		ee=a.rfind(bb);
        while(a.find(b)!=-1){
		 	x=a.find(b);
			 for(int i=x,k=0;k<3;i++,k++){
				 a[i]=c[k];
			 }
	}
	for(int i=mm;i<=ee;i++){
		a[i]=d[i];
	}	
		cout<<a;
}
	
	return 0;
}

红石信号源 :

红石之间的连接顺序是根据输入顺序决定的,并且能量传递是沿着红石线路传递的,传递的时候只能沿着线往前传或者往后传,可以将连接所有红石的二维图转换成一维的数轴;

注意:第一个点不一定是1=(0,0)!!!!;

一颗红石信号源能让d颗红石能量值大于等于m;

d=(15-m)*2+1;(红石信号源向两端传递能量,+1是它自己本身的颗数)

以d为一个周期,总共有sum长度。则最后结果为sum/d,

若sum%d有余数,则还需要一颗红石信号源

#include<bits/stdc++.h>
using namespace std;
#define int long long
 int n,m,sum=1;
 int x[200010],y[200010];
signed main(){
	cin>>n>>m;
    x[0]=0;
    y[0]=0;
	for(int i=1;i<=n;i++){
		cin>>x[i]>>y[i];
		if(i!=1)sum+=abs(x[i-1]-x[i])+abs(y[i-1]-y[i]);
	}
   
	int d=(15-m)*2+1;
	int ans=sum/d+(sum%d?1:0);
    if(m==0)cout<<0<<endl;
	else cout<<ans<<endl;
	return 0;
}

cy的倒金字塔工厂:

模拟题:

题意流水线上不为空时,若半成品中没有东西,直接放入即可,若有东西,半成品中最上面的长度小于将要放上来的长度,并且长度差不超过规定的m,就可以直接放入半成品中,若没有满足条件,查找盒子上第一个块的长度满不满足长度,若满足,将其提取出来,放入半成品中,将不满足的块放入盒中。

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
signed main()
{
	cin>>n>>m;
	stack<int>a;
	stack<int>box;
	stack<int>half;

	queue<int>rub;
	for(int i=0;i<n;i++){
		int x;
		cin>>x;
		a.push(x);
	}
	while(!a.empty()||!box.empty()){
	while(!a.empty()){
		if(half.empty()){
			half.push(a.top());
			a.pop();
		}
		else {
			if(a.top()>half.top()&&a.top()-half.top()<=m){
				half.push(a.top());
				a.pop();
			}
			else{
				if(!box.empty()&&box.top()>half.top()&&box.top()-half.top()<=m){
					half.push(box.top());
					box.pop();
				}
				box.push(a.top());
				a.pop();
			}
		}
		}
	if(a.empty()){
		if(half.size()>=2){
			while(!half.empty()){
				cout<<half.top()<<" ";
				half.pop();
			}
			cout<<endl;
		}
		else {
			rub.push(half.top());
			half.pop();
		}
	stack<int>t;
		while(!box.empty()){
			t.push(box.top());
			box.pop();
		}
		while(!t.empty()){
			a.push(t.top());
			t.pop();
		}
	}
	}
	while(!rub.empty()){
		cout<<rub.front()<<" ";
		rub.pop();
	}
	return 0;
}

swj学长的精灵融合:

低级精灵:1 2 4 7 11;(第二个在第一个的基础上加1,第三个在第二个的基础上加2,第四个在第三个的基础上加三,以此类推);

中级精灵:1 3 7 13 21;(第i个在i-1的基础上加2*(i-1))

高级精灵:1 6 16 31 51;(第i个在i-1的基础上加5*(i-1));

全都是0:

题意是只减数位上的任意一个数,不是任意减,并且比如16,16-6=10,此时10减的是10上对应数位的数字,不在是16数位上对应的数字;

#include<bits/stdc++.h>
using namespace std;
int v[1000006],ans;
int main(){
	string n;
	cin>>n;
	while(1){
		ans++;
		int l=n.size();
		for(int i=0;i<l;i++){
			v[i]=n[i]-'0';	
		}
		sort(v,v+l);
		int y=stol(n);
		n=to_string(y-v[l-1]);
		if(y-v[l-1]<10)break;
		else if(y-v[l-1]==10){
			ans+=2;
			break;
		}
	}
	cout<<ans;
	return 0;
}

相加余三:

此题是选一种操作一直操作才去,不是都可以选!!!

只需要将三种操作分别算一遍,求最大值即可;

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; 
typedef pair<int, int> PII; 
const int N = 2e5+10;
ll n, m, k,max1;
int a[2005];
ll ff1(int n,int a[]){
	int j=1,b=n,num=0;
	while(b<=n){
		num+=(a[j]+a[b])%3;
		j+=2;
		b+=2;
	}
	return num;
}
ll ff2(int n,int a[]){
	int j=n-1,b=n,num=0;
	while(j>=1){
		num+=(a[j]+a[b])%3;
		j-=2;
		b-=2;
	}
	return num;
}
ll ff3(int n,int a[]){
	int j=1,b=n,num=0;
	while(b>j){
		num+=(a[j]+a[b])%3;
		j++;
		b--;
	}
	return num;
}

void sovle(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	max1=max(ff1(n,a),max1);
	max1=max(ff2(n,a),max1);
	max1=max(ff3(n,a),max1);
	cout<<max1;
}
int main()
{    
	ios::sync_with_stdio(false), cin.tie(0),cout.tie(0); 
	int t = 1; 
	
	while (t --){
		sovle();
	}
	
	return 0;
}

□□,□□!

输出签到题:

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout<<"yuan shen, qi dong!";
	return 0;
}

比较大小

数学图像,其中当x=1时为零界点

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	double x;
	cin>>x;
	if(x>1)cout<<">";
	else if(x==1)cout<<"=";
	else cout<<"<";
	return 0;
}

基于金铲铲的期望学习

读题带公式就可以了

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
	
	double x;
	cin>>x;
	if(x<=8){
		double y=2;
		printf("%.2f",y);
	}
	else {
		int f=x+8;
		double ans=1+8.0/x;
		printf("%.2f",ans);
	}
	
	return 0;
}

 奇怪的克制倍数

仔细读题就能做

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
	
	double a,b,c,d,ans1,ans2,ans;
	cin>>a>>b>>c>>d;
	if(a==0||b==0){
		 ans1=(a+b)/4.0;
	}
    else if(a==2&&b==2)ans1=a+b;
	else {
		ans1=(a+b)/2.0;
	}
	if(c==0||d==0){
		ans2=(c+d)/4.0;
	}
    else if(c==2&&d==2)ans2=c+d;
	else {
		 ans2=(c+d)/2.0;
	}
	ans=(ans1+ans2)/2.0;
	printf("%.6f",ans);
	return 0;
}

 加纳~

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10 ;
int n , v[N] ;
char s;
string ans;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n,m,k;
	cin>>n>>m>>k;
	int y=k/n;
	int u=k%n;
	if(u>=m){
		y++;
	}
	cout<<y;
	return 0;
}

 找除数

约数考点:任何正整数都可以写成质数的几次方相乘的形式

n=p1^x∗p2^y∗p3^z……,是素数,n的除数的数量就=(x+1)(y+1)(z+1).....;

约数等于(次方+1)相乘,至于为什么+1;

举一个例子:12=2^2+3;

                         约数=1*2*2 * 1*3;(质因子本身也是一个除数)

此题目中还用到了线性筛,可以很快找到谁是质数。

#include <bits/stdc++.h>
using namespace  std;
#define  PII pair<int,int>
int prime[1000005];
int flag[1000005];
int cnt=0;
void get_prime(int x){
	for(int i=2;i<=x;i++){
		if(flag[i]==0){
			prime[cnt++]=i;
		}
		for(int j=0;i*prime[j]<=x;j++){
			flag[i*prime[j]]=1;
			if(i%prime[j]==0){
				break;
			}
		} 
		
	}
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	int t,n;
	get_prime(100000);
	cin>>t;
	while(t--){
		cin>>n;
		vector<int>g;
		for(int i=0;prime[i]<=n/prime[i]&&i<cnt;i++){
			int y=0;
			while(n%prime[i]==0){
				y++;
				n/=prime[i];
			}
			if(y){
				g.push_back(y);
			}
		}
		if(n>1)g.push_back(1);
			int ans=1;
			for(auto l: g){
				ans=ans*(l+1);
			}
		cout<<ans<<endl;
		
	}
	
	return 0;
}

  • 26
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值