SMU Winter 2024 Round #2 (Div.2)题解

A.P6056 [加油武汉] SIR 模型

思路

注意全感染和全恢复的情况

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n, a[100005],t[100005]={0};
char c[100005];


int32_t main() {
	int T;
	//cin>>T;
	T = 1;
	while (T--) {
		int s,i,r=0;
		double b,y;
		cin>>s>>i>>n>>b>>y;
		for(int j=0;j<n;j++){
			int x=ceil(b*s*i),m=ceil(y*i);
			if(s>=x){
				i+=(x-m);
				s-=x;
			}else{
				i+=(s-m);
				s=0;
			}
			r+=m;
		}
		cout<<s<<' '<<i<<' '<<r<<endl;
	}
	return 0;
}

B.P1765 手机

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n, a[100005],t[26]={1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4};
char c[100005];


int32_t main() {
	int T;
	//cin>>T;
	T = 1;
	while (T--) {
		cin.getline(c,1323);
		int s=0;
		for(int i=0;i<strlen(c);i++){
			if(c[i]==' ')s++;
			else if(c[i]>='a'&&c[i]<='z')s+=t[c[i]-'a'];
		}
		cout<<s;
	}
	return 0;
}

C.P4305 [JLOI2011] 不重复数字

思路

用哈希表去重

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

unordered_map<int,int> hm;
int a[100005],n;


int32_t main() {
	int T;
	cin>>T;
	//T = 1;
	while (T--) {
		cin>>n;
		int pos=0;
		for(int i=0;i<n;i++){
			cin>>a[pos];
			if(hm.find(a[pos])!=hm.end()){
				hm[a[pos]]++;
			}else{
				hm[a[pos]]=1;
				pos++;
			}
		}
		for(int i=0;i<pos;i++){
			cout<<a[i]<<' ';
		}cout<<endl;
		hm.clear();
	}
	return 0;
}

D.P1145 约瑟夫

思路

枚举m即可

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

unordered_map<int,int> hm;
int a[100005],k,mn=INT64_MAX;


int32_t main() {
	int T;
	//cin>>T;
	T = 1;
	while (T--) {
		cin>>k;
		int m=k+1,f=0;
		while(!f){
			int pos=0;
			for(int i=0;i<k;i++){
				pos=(pos+m-1)%(2*k-i);
				if(pos<k)break;
				if(i==k-1)f=1;
			}if(f)break;
			m++;
		}
		cout<<m<<endl;
	}
	return 0;
}

E.P8742 [蓝桥杯 2021 省 AB] 砝码称重

思路

变种背包问题,计算方案数即可

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

unordered_map<int, vector<int> > hm;
int a[100005], n,f[105][100005];


int32_t main() {
	int T;
	//cin>>T;
	T = 1;
	while (T--) {
		cin >> n;
		int s = 0, sum = 0;
		for (int i = 1; i <= n; i++) {
			cin >> a[i];
			sum += a[i];
			
		}
		for(int i=1;i<=n;i++){
			for(int j=sum;j;j--){
				if(j==a[i])f[i][j]=1;
				else if(f[i-1][j])f[i][j]=1;
				else if(f[i-1][j+a[i]])f[i][j]=1;
				else if(f[i-1][abs(j-a[i])])f[i][j]=1;
			}
		}  
		for(int i=1;i<=sum;i++){
			if(f[n][i])s++;
		}
		cout<<s;
	}
	return 0;
}

F.P6473 [NOI Online #2 入门组] 未了

思路

贪心,先降序排序,存前缀和,再二分查找

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

unordered_map<int, vector<int> > hm;
int a[200005], n,b[200005]={0};


int32_t main() {
	int T;
	//cin>>T;
	T = 1;
	while (T--) {
		int l,v,sum=0;
		cin >> n>>l>>v;
		double t=(double)l/v;
		for(int i=0;i<n;i++){
			cin>>a[i];
			sum+=a[i];
		}
		
		sort(a,a+n);
		for(int i=1;i<=n;i++){
			b[i]=b[i-1]+a[n-i];
		}
		int q;
		cin>>q;
		while(q--){
			int x;
			cin>>x;
			if(x*v<l)cout<<0<<endl;
			else if(x*v>=(l+sum))cout<<-1<<endl;
			else{
				cout<<upper_bound(b+1,b+n+1,x*v-l)-b<<endl;
			}
		}
	}
	return 0;
}

G.P8808 [蓝桥杯 2022 国 C] 斐波那契数组

思路

\(a_0=a_1\)得,题目所定义的数组满足\(a_i=a_0*F_i\)\(F_i\)为斐波那契数),则对所给数组的每个\(a_i\)分别判断是否能被\(F_i\)整除,并枚举修改次数

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

unordered_map<int, vector<int> > hm;
int a[200005], n,b[200005]={1,1},mn=INT64_MAX;


int32_t main() {
	int T;
	//cin>>T;
	T = 1;
	while (T--) {
		cin>>n;
		for(int i=0;i<n;i++){
			cin>>a[i];
		}
		int s=0;
		if(a[0]!=a[1])s++;
		int q=a[0]*2,p=a[0];
		for(int i=2;i<n;i++){
			if(a[i]!=q)s++;
			b[i]=q/a[0];
			q=p+q;
			p=q-p;
		}
		mn=s;
		int t;
		for(int i=1;i<n;i++){
			if(a[i]%b[i]==0){
				t=a[i]/b[i];
				s=0;
				for(int i=0;i<n;i++){
					if(a[i]!=t*b[i])s++;
				}
				mn=min(s,mn);
			}
		}
		cout<<mn;
		
	}
	return 0;
}

H.[ABC325E] Our clients, please wait a moment

思路

\(dij\)算法,由题可知,可以从坐车切换为坐火车,但不能从坐火车切换为坐车,记车为0,火车为1,\(MN[i][0]\)为坐车到节点\(i\)的最少时间,\(MN[i][1]\)为坐火车到节点\(i\)的最少时间。
可以写出状态更新方程\(\begin{cases} MN[i][0]=min(MN[i][0],MN[m][0] + D[m][i] * A)\\ MN[i][1]=min(MN[i][1],min(MN[m][0],MN[m][1]) + D[m][i] * B + C)\\ \end{cases}\)
最后暴力枚举

代码

#include <bits/stdc++.h>
#define int long long
#define MAX (int)1e18
using namespace std;

unordered_map<int, vector<int> > hm;
int a[1005][1005], n;
int u, p, o;
vector<int> g[1005], vis(1005, 0);
vector<vector<int>> mn(1005, vector<int>(2, MAX));

int32_t main() {
	int T;
	//cin>>T;
	T = 1;
	while (T--) {
		cin >> n >> u >> p >> o;
		int m = 0, x =MAX, y = MAX;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				cin >> a[i][j];
			}
		}
		vis[0] = 1;
		mn[0][0]=0;
		mn[0][1]=0;
		for (int t = 0; t < n; t++) {
			int pos;
			for (int i = 0; i < n; i++) {
				if (!vis[i]) {
					mn[i][0] = min(mn[i][0], mn[m][0] + a[m][i] * u);
					mn[i][1] = min(mn[i][1], a[m][i] * p + o + min(mn[m][1], mn[m][0]));
					if (x >= mn[i][0] && y >= mn[i][1]) {
						x = mn[i][0];
						y = mn[i][1];
						pos = i;
					}
				}
				mn[i][0]=min(mn[i][0],mn[m][0]+a[m][i]*u);
				mn[i][1]=min(mn[i][1],a[m][i] * p + o + min(mn[m][1], mn[m][0]));
			}
			m=pos;
			vis[m]=1;
			x = MAX, y =MAX;
		}
		cout << min(mn[n - 1][0], mn[n - 1][1]);
	}
	return 0;
}

I.P8786 [蓝桥杯 2022 省 B] 李白打酒加强版

思路

\(a[i][j][k]\)为第\(i\)次看了\(j\)次花还剩\(k\)斗酒的方案数。
dp方程为\(\begin{cases} a[i+1][j+1][k-1]=(a[i][j][k]+a[i+1][j+1][k-1])(mod_{10000})\\ a[i+1][j][k*2]=(a[i][j][k]+a[i+1][j][k*2])(mod_{10000})\\ \end{cases}\)
注意\(k\)的范围即可。

代码

#include <bits/stdc++.h>
#define int long long
#define MOD 1000000007
using namespace std;

unordered_map<int, vector<int> > hm;
int a[205][105][105], n,m;



int32_t main() {
	int T;
	//cin>>T;
	T = 1;
	while (T--) {
		cin>>n>>m;
		a[0][0][2]=1;
		for(int i=0;i<m+n;i++){
			for(int j=0;j<m;j++){
				for(int k=0;k<m;k++){
					if(k)a[i+1][j+1][k-1]=(a[i][j][k]+a[i+1][j+1][k-1])%MOD;
					if(2*k<=100)if(k)a[i+1][j][k*2]=(a[i][j][k]+a[i+1][j][k*2])%MOD;
				}
			}
		}
		cout<<a[m+n][m][0];
	}
	return 0;
}

J.P1685 游览

思路

拓扑排序,每次更新入度为0的点,dp方程为\(\begin{cases} cnt[v]+=cnt[u]\\ s[v]+=s[u]+cnt[u]*w\\ \end{cases}\)

代码

#include <bits/stdc++.h>
#define int long long
#define MAX (int)1e18
using namespace std;

unordered_map<int, vector<int> > hm;
int  n,x,y,t,sum=0;
vector<pair<int,int>> g[10005];
vector<int> cnt(10005, 0),ru(10005, 0);
vector<int> mn(10005, 0);
vector<int > q;

void f(int s){
	for(int i=0;i<g[s].size();i++){
		cnt[g[s][i].first]=(cnt[g[s][i].first]+cnt[s])%10000;
		mn[g[s][i].first]=(mn[g[s][i].first]+mn[s]+cnt[s]*g[s][i].second)%10000;
		ru[g[s][i].first]--;
		if(!ru[g[s][i].first])f(g[s][i].first);
	}
}


int32_t main() {
	int T;
	//cin>>T;
	T = 1;
	while (T--) {
		int m,s;
		cin >> n >> m>>x>>y>>t;
		for (int i = 0; i < m; i++) {
			int u,v,w;
			cin>>u>>v>>w;
			u--;v--;
			g[u].emplace_back(make_pair(v,w));
			ru[v]++;
		}
		cnt[x-1]=1;
		f(x-1);
		cout<<(mn[y-1]+t*(cnt[y-1]-1))%10000;
	}
	return 0;
}
posted @ 2024-01-28 01:26  ptlks  阅读(11)  评论(0编辑  收藏  举报