牛客小白月赛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;
}