第六周训练+周赛补

7-1 小北的包

#include <bits/stdc++.h>
using namespace std;
int main() {
	int n, w;
	cin >> n >> w;
	vector<int>ans(w + 1, 0);
	for (int i=0;i<n;i++)
	{
		int t1,t2;
		cin >> t1 >> t2;
		for (int i1 = w-t1; i1 >= 0; i1--) {
			ans[i1 + t1] = max(ans[i1] + t2, ans[i1 + t1]);
		}
	}
	cout << ans[w] << endl;
	return 0;
}

背包问题

7-2 铺瓷砖

#include <bits/stdc++.h>
using namespace std;
int main() {
	int n;
	cin >> n;
	vector<unsigned long long int>ans = {1,1,3};
	for (int i = 0; i < n; i++) {
		int t;
		cin >> t;
		for (int i1 = ans.size()-1; i1 <= t; i1++) {
			ans.push_back(ans[i1] + ans[i1 - 1] * 2);
		}
		cout << ans[t] << endl;
	}
}

fn可以由fn-1+2*1瓷砖和fn-2+2*1*2+2*2瓷砖不能与fn-1重复

7-3 小源爱写题

#include <bits/stdc++.h>
using namespace std;
unsigned long long ans = 0;
vector<vector<unsigned long long>>mem(510,vector<unsigned long long>(260));
void dfs(int n, int i) {
	if (n == 0)ans++;
	if (n < 0)return;
	if (mem[n][i] != 0) {
		ans += mem[n][i];
		return;
	}
	unsigned long long last = ans;
	for (int t = i + 1;t<=(n-1)/2;t++) {
		dfs(n - t, t);
	}
	if (i < n) {
		ans++;
	}
	unsigned long long now = ans;
	mem[n][i] = now-last;
}
int main() {
	int n;
	cin >> n;
	/*
	1 2 3   (n-1)/2
	*/
	for (int i = 1; i <= (n - 1) / 2; i++) {
		dfs(n - i, i);
	}
	cout << ans << endl;
	return 0;
	
}

记忆化相当于保存动态数组每次调用时自动使用

7-4 自动补全

#include <bits/stdc++.h>
using namespace std;
int main() {
	int n;string s1;
	cin >> s1;
	cin >> n;
	string ans;
	bool f=false;
	for (int i = 0; i < n; i++) {
		string temp;
		cin >> temp;
		if (temp.find(s1) != string::npos) {
			if (f) {
				ans = ans < temp ? ans : temp;
			
			}
			else {
				ans = temp;
				f = true;
			}
		}
	}
	if (ans != "")cout << ans << endl;
	else cout << s1 << endl;
	return 0;
	
}

find找符合条件的然后保存

7-5 数组

#include <bits/stdc++.h>
using namespace std;
int main() {
	int n,m;
	cin >> n >> m;
	vector<int>shu(n,0);
	vector<pair<int, int>>cao(m);
	for (int i = 0; i < n; i++) {
		cin >> shu[i];
	}
	for (int i = 0; i < m; i++) {
		cin >> cao[i].first >> cao[i].second;
	}
	vector<int>ans; int cha = 0;
	for (int i = 0; i < n; i++) {
		int max = shu[i];
		for (int i1 = 0; i1 < n; i1++) {
			if (i == i1)continue;
			int min = shu[i1];
			vector<int>tempxu;
			for (int i2 = 0; i2 < m; i2++) {
				if (i1+1 >= cao[i2].first) {
					if (i1+1 <= cao[i2].second) {
						if((i+1>cao[i2].second)||(i+1<cao[i2].first))
						tempxu.push_back(i2);
					}
				}
			}
			int mt = max - min + tempxu.size();
			if (cha < mt) {
				cha = mt;
				ans = tempxu;
			}
		}
	}
	cout << cha << endl;
	cout << ans.size() << endl;
	for (int i = 0; i < ans.size(); i++) {
		cout << ans[i] + 1 << ' ';
	}
	return 0;
	
}

在某一区域内减一,如果最大值和最小值都在或都不在没有影响

如果仅最小值再结果会变大暴力即可

7-6 最小生成树

#include <bits/stdc++.h>
using namespace std;
struct san {
	int x=0, y=0, z=0;
};
bool cmp(san s1,san s2) {
	return s1.z < s2.z;
}
class mycmp {
public:
    bool operator()(san s1,san s2) {
	return s1.z < s2.z;
}
};
int gengxin(vector<int>&tong){
    vector<int>ans(tong.size(),0);
    int count=0;
    for(int i=1;i<tong.size();i++){
        int le=i;
        while (tong[le]!=le)
	    {
			le = tong[le];
		}
        tong[i]=le;
        ans[le]=1;
    }
    for(int i=1;i<tong.size();i++){
        if(ans[i])count++;
    }
    return count;
}
int findtong(vector<int>&tong,int i){
    while (tong[i]!=i)
	{
		i = tong[i];
	}
    return i;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n;
	cin >> n;
	int m;
	cin >> m;
	int ans=0;
	vector<san>bian(m);
	vector<int>tong(n+1);
	for (int i = 0; i < n+1; i++) {
		tong[i] = i;
	}
	for (int i = 0; i < m; i++) {
		cin>>bian[i].x>>bian[i].y>>bian[i].z;
	}
	sort(bian.begin(), bian.end(), cmp);
	for (int i = 0; i < m; ) {
		auto it = upper_bound(bian.begin(), bian.end(),bian[i],mycmp());
		auto it1 = lower_bound(bian.begin(), bian.end(),bian[i],mycmp());
		vector<san>temp(it1, it);
		i += temp.size();
		//cout<<i<<endl;
        vector<int>pan1(temp.size()),pan2(temp.size());
        int pan1size=0;
        int last=gengxin(tong);
		for (int i1 = 0; i1 < temp.size(); i1++) {
		    //cout<<temp[i1].x<<" "<<temp[i1].y<<" "<<temp[i1].z<<endl;
			int le = findtong(tong,temp[i1].x);
			int ri = findtong(tong,temp[i1].y);
			if (le != ri){
			    pan1[pan1size]=le;
			    pan2[pan1size]=ri;
			    pan1size++;
			}
		}
		//cout<<pan1size<<' '<<pan1.size()<<endl;
		for (int i1 = 0; i1 < pan1size; i1++) {
			int le =findtong(tong,pan1[i1]);
			int ri =findtong(tong,pan2[i1]);
			if(le<ri)swap(le,ri);
			tong[ri] = le;
		}
		int now=gengxin(tong);
		ans+=pan1size+now-last;
		if(now==1)break;
	}
	cout << ans << endl;
	return 0;
	
}

很遗憾,考试的时候有和题解很相似的想法,不过由于没有真正的答案,自己不断修改,但是始终运行超时,发现连接通路的时候没考虑大小,结果导致死循环而超时

P1135 奇怪的电梯

#include <bits/stdc++.h>
using namespace std;
struct dui{
    int lu;
    int i;
};
bool hefa(int i,int n){
    if(i>=0){
        if(i<=n)
            return true;
    }
    return false;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n,a,b;
	cin>>n>>a>>b;
	if(a==b){
	    cout<<0<<endl;
	    return 0;
	}
	vector<int>cao(n+1);
	for(int i=1;i<=n;i++){
	    cin>>cao[i];
	}
	queue<dui>bu;
	dui temp;
	temp.lu=a;
	temp.i=0;
	bu.push(temp);
	bool find=false;
	vector<int>ans(n+1,0);
	while(!bu.empty()){
	    temp=bu.front();
	    bu.pop();
	    if(ans[temp.lu])continue;
	    ans[temp.lu]=1;
	    dui next;
	    next.lu=cao[temp.lu]+temp.lu;
	    //cout<<cao[temp.lu]<<" "<<temp.lu<<endl;
	    if(next.lu==b){
	        find=true;
	        cout<<temp.i+1<<endl;
	        break;
	    }
	    if(hefa(next.lu,n)){
	        next.i=temp.i+1;
	        bu.push(next);
	    }
	    //cout<<next.lu<<" "<<next.i<<endl;
	    next.lu=-cao[temp.lu]+temp.lu;
	    if(next.lu==b){
	        find=true;
	        cout<<temp.i+1<<endl;
	        break;
	    }
	    if(hefa(next.lu,n)){
	        next.i=temp.i+1;
	        bu.push(next);
	    }
	    //cout<<next.lu<<" "<<next.i<<endl;
	}
	if(!find)cout<< -1<<endl;
	return 0;
}

没考虑a与b相等情况

P1443 马的遍历

#include <bits/stdc++.h>
using namespace std;
const int dx[8]={-1,-2,-2,-1,1,2,2,1};
const int dy[8]={2,1,-1,-2,2,1,-1,-2};
struct dui{
    int x,y;
    int i;
};
bool hefa(int i,int n){
    if(i>0){
        if(i<=n)
            return true;
    }
    return false;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n,m,x,y;
	cin>>n>>m;
	vector<vector<int>>ans(n+1,vector<int>(m+1,-1));
    queue<dui>bu;
    dui temp;
    cin>>temp.x>>temp.y;
    temp.i=0;
    bu.push(temp);
    while(bu.size()){
        dui next=bu.front();
        bu.pop();
        //cout<<next.x<<next.y<<next.i<<endl;;
        if(hefa(next.x,n)){
            if(hefa(next.y,m)){
                if(ans[next.x][next.y]==-1){
                    ans[next.x][next.y]=next.i;
                }else{
                    continue;
                }
            }
        }
        for(int i=0;i<8;i++){
            if(hefa(next.x+dx[i],n)){
                if(hefa(next.y+dy[i],m)){
                    temp.x=next.x+dx[i];
                    temp.y=next.y+dy[i];
                    temp.i=next.i+1;
                    //cout<<temp.x<<temp.y<<temp.i<<endl;;
                    bu.push(temp);
                }
            }
        }/**/
    }
    for(int i=1;i<=n;i++){
        for(int i1=1;i1<=m;i1++){
            cout<<ans[i][i1]<<" ";
        }
        cout<<endl;
    }
	return 0;
}

简单bfs 遍历即可

P3958 [NOIP2017 提高组] 奶酪

#include <bits/stdc++.h>
using namespace std;
struct zuo{
    int x,y,z;
};
bool keda(int r,zuo x,zuo y){
    return (sqrt(pow(x.x-y.x,2)+pow(x.y-y.y,2)+pow(x.z-y.z,2))<=2*r);
}
bool hefa(int i,int n){
    if(i>0){
        if(i<=n)
            return true;
    }
    return false;
}
bool nailao(){
    int n,h,r;
    cin>>n>>h>>r;
    vector<int>ans(n,0);
    vector<zuo>cun(n);
    queue<zuo>mem;
    for(int i1=0;i1<n;i1++){
        cin>>cun[i1].x>>cun[i1].y>>cun[i1].z;
        if(cun[i1].z<=r){
            ans[i1]=1;
            mem.push(cun[i1]);
        }
        
    }
    while(mem.size()){
        zuo temp=mem.front();
        mem.pop();
        //<<temp.x<<temp.y<<temp.z<<endl;
        if(temp.z+r>=h)return true;
        for(int i=0;i<n;i++){
            if(ans[i]==0){
                if(keda(r,temp,cun[i])){
                    //cout<<temp.x<<temp.y<<temp.z<<" ";
                    //cout<<cun[i].x<<cun[i].y<<cun[i].z<<endl;
                    //cout<<(sqrt(pow(temp.x-cun[i].x,2)+pow(temp.y-cun[i].y,2)+pow(temp.z-cun[i].z,2))>=2*r)<<endl;
                    //cout<<2*r<<endl;
                    ans[i]=1;
                    mem.push(cun[i]);
                }
            }
        }
        
    }
    return false;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int t;
	cin>>t;
	for(int i1=0;i1<t;i1++){
	    if(nailao()){
	        cout<<"Yes"<<endl;
	    }else {
	        cout<<"No"<<endl;
	    }
	}
	return 0;
}

遍历时不断重复找可达地方然后放入队列

P1162 填涂颜色

#include <bits/stdc++.h>
using namespace std;
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,-1,1};
struct zuo{
    int x,y;
};

bool hefa(int i,int n){
    if(i>=0){
        if(i<=n)
            return true;
    }
    return false;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n;
	cin>>n;
	vector<vector<int>>ans(n+2,vector<int>(n+2,2));
	for(int i=1;i<=n;i++){
	    for(int i1=1;i1<=n;i1++){
	        int temp;
	        cin>>temp;
	        if(temp){
	            ans[i][i1]=1;
	        }
	    }
	}
	std::queue<zuo>bu;
	zuo temp;
	temp.x=0;
	temp.y=0;
	bu.push(temp);
	while(bu.size()){
	    zuo next=bu.front();
	    bu.pop();
	    if(hefa(next.x,n+1)){
	        if(hefa(next.y,n+1)){
	           if(ans[next.x][next.y]==2){
	               ans[next.x][next.y]=0;
	               for(int i=0;i<4;i++){
	               temp.x=next.x+dx[i];
	               temp.y=next.y+dy[i];
	               bu.push(temp);
	               }
	               
	           }
	           
	           
	        }
	    }
	}
	for(int i=1;i<=n;i++){
	    for(int i1=1;i1<=n;i1++){
	        cout<<ans[i][i1]<<" ";
	    }cout<<endl;
	}
	return 0;
}

初始化直接设为2;

再加厚一圈

从 0 0开始搜索 只有封闭圈内搜不到;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值