牛客小白月赛88

牛客小白月赛88 \(A\)~\(D\)(补题ing)

\(A\)超级闪光牛可乐

题意

就是从n种零食中,找出不大于1000以内的价值和并输出就行

\(ACcode\)
#include<bits/stdc++.h>
const int N = 100010;
using namespace std;
int x;
int n;

void solve(){
	cin >> x;
	cin >> n;
	char ch='a';
	int v=0;
	for(int i=1;i<=n;i++){
		char ch1;
		int t;
		cin >> ch1 >> t;
		if(v<t){
			ch = ch1;
			v = t;
		} 
	}
	int cnt = (x+v-1) / v;
	if(cnt>1000){
		cout << -1 << endl;
		return ;
	} 
	for(int i=0;i<cnt;i++){
		cout << ch;
	}
	
}

int main(){
	int T = 1;
//	cin >> T;
	while(T--){
		solve();
	}
	return 0;
}

\(B\)人列计算机

题意

我先前用\(getchar\)一个字符一个字符的扣,结果牛客的输入给我干蒙了,然后就开始乱搞了。

主要就是判读是与门,或门,非门的位置

与门:就是当读入的字符串长度为\(1\),并且$s[0] \equiv $'&'

非门:就是当读入的字符串长度为\(1\),并且$s[0]\equiv $'1'

或门:除上述两个之外的状态

\(AC\)code
#include<bits/stdc++.h>
const int N = 1010;
using namespace std;
int n;
string s;
void solve(){
	int a=-1 , b=-1;
	int col = -1;
	while(cin >> s){
		if(s.size()==1){
			if(col==-1&&s[0]=='1')col = 3;
			if(col==-1&&s[0]=='&') col = 1;
			}
		for(int i=0;i<s.size();i++){
			if(i==0&&s[i]<='9'&&s[i]>='0'){
				if(a==-1) a = s[i]-'0';
				else b = s[i] - '0';
			}
		}
	}
	if(col==-1) col = 2;
	if(col==1){
		cout << (a&&b) << endl;
	}
	else if(col==2){
		cout << (a||b) << endl;
	}
	else if(col==3){
		cout << (!a) << endl;
	}
}

int main(){
	int T = 1;
//	cin >> T;
	while(T--){
		solve();
	}
	return 0;
}

\(C\)时间管理大师

题意

给你n个时间,你需要得出该时刻前\(1,3,5\)的时刻,且不能重复

大模拟,直接看吧

\(AC\)code
#include<bits/stdc++.h>
const int N = 1010;
using namespace std;
typedef pair<int,int> PII;
int n;
int dx[]={0,1,3,5};

bool cmp(PII a,PII b){
	if(a.first!=b.first) return a.first<b.first;
	return a.second < b.second;
}

void solve(){
	cin >> n;
	vector<PII> col;
	vector<PII> ans;
	map<PII,int> st;
	for(int i=0;i<n;i++){
		int h , m;
		cin >> h >> m;
		col.push_back({h,m});
		for(int j=1;j<=3;j++){
			int th , tm;
			tm = m - dx[j];
			th = h;
			if(tm<0) tm += 60 , th-=1;
			if(th<0) th += 24;
			if(!st[{th,tm}]){
				st[{th,tm}] = 1;
				ans.push_back({th,tm});
			}
		}
	}
	sort(ans.begin(),ans.end(),cmp);
	cout << ans.size() << endl;
	for(int i=0;i<ans.size();i++){
		cout << ans[i].first << " " << ans[i].second << endl;
	}
}

int main(){
	int T = 1;
//	cin >> T;
	while(T--){
		solve();
	}
	return 0;
}

\(D\)我不是大富翁

题意

就是进行\(m\)次操作(加或者减),看最后的数值\(mod\) \(n\)是否能够为\(0\).

下意识就写暴力了,我是笨蒟蒻

暴力的码(剪枝)
#include<bits/stdc++.h>
const int N = 100010;
using namespace std;
typedef pair<int,int> PII;
int n,m;
bool fla = 0;
int col[N];
map<PII,int> st;

int dfs(int step,int idx){
	if(st[{step,idx}]) return 0;
	st[{step,idx}] = 1;
	if(step>=m){
		if(idx%n==1) return 1;
		else return 0;
	}
	int t = (idx + col[step]) % n;
	if(dfs(step+1,t)) return 1;
	t = (idx-col[step])%n;
	if(dfs(step+1,t)) return 1;
    
    return 0;
}

void solve(){
	cin >> n >> m;
	for(int i=0;i<m;i++){
		cin >> col[i];
	}
	fla = dfs(0,1);
	if(fla) cout << "Yes" << endl;
	else cout << "No" << endl;
}

int main(){
	int T = 1;
//	cin >> T;
	while(T--){
		solve();
	}
	return 0;
}

结果当然\(mle\)

思路

数字三角形的变形题,记得初始化数组 (\(wa\)了)

第一步操作只能从\(a[1]\)或者\(-a[1]\)开始,之后的操作只有加,减两个状态,用\(dp\)表示进行的操作数,\(dp[i][j]\) 表示第\(i\)次操作时,走到第\(j\)格的操作数。

可以得到状态转移方程是

\(dp[i][j]\) = \(max\)(\(dp[i-1][j \pm a[i]]\)) + \(1\)

其中\(j-a[i]\)\(j\) + \(a[i]\)\(mod\) \(n\) 使其在\(0\)~\(n\)之间

最后特判一下\(dp[m][0]\) \(==m\) 即可

\(AC\)code
#include<bits/stdc++.h>
const int N = 5010;
using namespace std;
typedef pair<int,int> PII;
int n,m;
bool fla = 0;
int col[N];
int f[N][N];

void solve(){
	cin >> n >> m;
	for(int i=1;i<=m;i++){
		cin >> col[i];
		col[i]%=n;
	}
	f[1][col[1]] = 1;
	int x = col[1] - n;
	while(x<0) x+=n;
	f[1][x] = 1;
	for(int i=2;i<=m;i++){
		for(int j=n;j>=0;j--){
			int t1 = j - col[i];
			while(t1<0) t1+=n;
			t1 %= n;
			int t2 = (j+col[i])%n;
			f[i][j] = max(f[i-1][t1],f[i-1][t2]) + 1;
		}
	}
	if(f[m][0]==m) cout << "Yes" << endl;
	else cout << "No" << endl;
}

int main(){
	int T = 1;
//	cin >> T;
	while(T--){
		solve();
	}
	return 0;
}
posted @ 2024-03-09 11:39  xlxDH  阅读(11)  评论(0编辑  收藏  举报