7.16暑假集训记录

昨天上午感觉效率还是很高的,下午就不太行了,vp了一场cf,c没出来,真的菜。

可能是好久没有打cf了吧,自己思维方面是真的菜,昨天晚上还想打cf的,结果a题直接没思路....

一个小时都没出来,我是真的菜啊。。。

感觉还是好久没做的原因啊,思维完全跟不上,也不在思考题目,都在梦游...

我是菜鸡。

感觉学了挺多的算法了,但是做题的时候还是不会啊....感觉自己思维还是不太行啊。

以后:洛谷题单+cf(1周三场)+多校都得打啊。

合理利用起来时间很关键!!

P3884 [JLOI2009] 二叉树问题

这题感觉还是很有意思的,

但是我没搞懂最短距离是怎么算出来的...深度就是dfs搜即可,设一个vis【】数组记录在搜索过程中每一层出现的次数即可,然后求最大的即可

最短距离的化就是floyd即可了,其实也就是个板子题目

int check(string a,string b){
	
	for(int i=1;i<=min(a.length(),b.length());i++){//枚举重叠部分
		int flag=1;
		for(int j=0;j<i;j++){
			if(b[j]!=a[a.length()-i+j])flag=0;
		} 
		if(flag)return i;
	}
	return 0;
	
}

P1019 [NOIP2000 提高组] 单词接龙

这题写的时候就有思路了,但是读题读错了,没看见每个单词最多出现2次,而且匹配也匹配错了,我真的服了...

思路还是很好想的就是dfs+回溯

说下匹配的事,需要贪心,要使得最后答案长度最大,我们需要最小的匹配即可,即只要能匹配上就break即可

匹配函数如下:其实还是很难想的...

int check(string a,string b){
	
	for(int i=1;i<=min(a.length(),b.length());i++){//枚举重叠部分
		int flag=1;
		for(int j=0;j<i;j++){
			if(b[j]!=a[a.length()-i+j])flag=0;
		} 
		if(flag)return i;
	}
	return 0;
	
}

 我调了快2个小时,烦死...

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
#include <list>
using namespace std;
typedef  long  long ll ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
inline int read(){
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = (x<<1) + (x<<3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}
void print(__int128 num) {
	if(num) {
		print(num/10);
		putchar(num%10+'0');
	}
}
ll ex_gcd(ll a,ll b,ll& x,ll& y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}

	ll d=ex_gcd(b,a%b,y,x);
	y=y-a/b*x;
	return d;
}
int ans=0; 
vector<string>a;
int n;
int vis[30];
char ops;
int check(string a,string b){
	
	for(int i=1;i<=min(a.length(),b.length());i++){//枚举重叠部分
		int flag=1;
		for(int j=0;j<i;j++){
			if(b[j]!=a[a.length()-i+j])flag=0;
		} 
		if(flag)return i;
	}
	return 0;
	
}
void dfs(string s,int len){ 
	
	ans=max(ans,len);
	 
	for(int i=0;i<n;i++){	
		if(vis[i]>=2)continue;
		int c=check(s,a[i]);
		if(c==0)continue;
		vis[i]++;	
		
		dfs(a[i],len+a[i].length()-c);		
		vis[i]--;
	}
}

int main(){
	
	cin>>n;
	 
	string s1;
	
	for(int i=1;i<=n;i++){	
		cin>>s1;	
		a.push_back(s1);		
	}
	
	
	cin>>ops;	
	for(int i=0;i<n;i++){		
		for(int j=0;j<=n;j++)vis[j]=0;
		if(a[i][0]==ops){
			vis[i]++;
			dfs(a[i],a[i].length());
			
		}	
	}
	
	cout<<ans<<endl;
	
	return 0;
}

昨天还学了Hash算法..

感觉还是比较简单的,就是进制,一般来说,进制采用31,131,1313比较好,能有效减少冲突。

我们用ull数组来存hash值...

为了取余来着...

ull Hash(string s){
	ull ans=0;
	ull p=131;
	for(int i=0;i<=s.length()-1;i++){
		ans=ans*p+s[i]-'a'+1;	
	}
	return ans;
}

昨天还vp了一场cf,出了2道题...排名5000多,我是真的菜啊...

感觉还是做到c题的时候,自己不能完全太专注,静下心来认真思考,老毛病了,高中考试就无法完全专注起来。不然也不会来青稞,也不知道应该怎么改变,反正尽量让自己专注起来吧

A:

A还是比较简单的,

主要情况分两类:x为1或者x不为1

x不为1的话,n就可以由n个1组成

如果x为1的话,结果可以由2和3组成,如果n==1的话就无解

B:

B题也是很简单的,但是做的时候自己思路不是很清晰就开始做了;

导致自己改了好久.....

我们发现如果c1-a1和b1-a1同号的话,答案+min(abs(c1-a1),abs(b1-a1));

b2-a2和c2-a2也是同理的

注意ans最初的赋值应该为1

C. 

这题就不会了..还是自己的思维跟不上啊

也可能是自己没有专注的想....(主要原因)

其实当时我想的是统计l和r之间每个字符出现的次数,如果次数>s中的数量,就可以,反之就不知道了,但这不是所有情况...

思路:贪心+思维

对于每一位我们希望每一个字符在s中出现的最晚,find(s,k)从第k个位置之后找s

比如l=1,r=3,s=1112222333,我们肯定在把3当作最好的

注意维护位置pos即可

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
#include <list>
using namespace std;
typedef  long  long ll ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
inline int read(){
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = (x<<1) + (x<<3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}
void print(__int128 num) {
	if(num) {
		print(num/10);
		putchar(num%10+'0');
	}
}
ll ex_gcd(ll a,ll b,ll& x,ll& y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}

	ll d=ex_gcd(b,a%b,y,x);
	y=y-a/b*x;
	return d;
}
int t;
string s;
int m;
string s1,s2;
int main(){
	cin>>t;
	while(t--){
	
		cin>>s>>m>>s1>>s2;
		
		int flag=0;
		int pos=0;
		int maxn=0;
		for(int i=0;i<m;i++){
			if(flag)break;
		  	 pos=maxn;
			for(char j=s1[i];j<=s2[i];j++){
	
				int cnt=s.find(j,pos);
				
				if(cnt>=s.length()){
					flag=1;
					printf("YES\n");
					break;
				}
				maxn=max(maxn,cnt+1);
			}
		}
		
		
		if(flag==0){
			printf("NO\n"); 
		}
		
	}
	
	
	return 0;
}

 

D:思维+贪心

虽然代码很短,但是还是不太好想

这题k一定等于前i个数的某个和

思路:求最小的子序列,然后前面的前缀和就是k了。

一直不太明白,我当初的思路就是贪心,为什么k不等于最大的子序列呢;

其实正确思路以及包含了这种思路了;而且更优

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
#include <list>
using namespace std;
typedef  long  long ll ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
inline int read(){
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = (x<<1) + (x<<3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}
void print(__int128 num) {
	if(num) {
		print(num/10);
		putchar(num%10+'0');
	}
}
ll ex_gcd(ll a,ll b,ll& x,ll& y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}

	ll d=ex_gcd(b,a%b,y,x);
	y=y-a/b*x;
	return d;
}
int t;
int n;
ll a[300005];
int main(){
	
	cin>>t;
	while(t--){
		cin>>n;
		ll sum=0,minn=0,ans,mc=0,x;
		for(int i=1;i<=n;i++){
			scanf("%lld",&x);
			sum=sum+x;
			mc=max(mc,sum);
			ll mx=sum-mc;
			
			if(mx<minn){
				minn=mx;
				ans=mc;		
				
			}
			
		}
		cout<<ans<<endl;			
	}
	
	return 0;
}

 

把握好时间,注重效率!!        

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值