很可惜的一场比赛,两小时调H题没调出来T_T,如果调出来就能被选上了。无限Sad(意难平,希望蓝桥杯不留遗憾。
文章目录
A题:蜗牛与井 签到
虽然是签到还wa了两发,有被自己菜到qwq
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define fi first
#define se second
#define endl '\n'
typedef long long ll;
typedef pair<int,int> PII;
const int mod1 = 1e9 + 7, mod2 = 998244353;
const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
inline int read()
{
int x = 0, f = 1;char ch = getchar();
while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
while (isdigit(ch)) {x = x * 10 + ch - 48; ch = getchar();}
return x * f;
}
ll h,x,y;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
cin>>h>>x>>y;
ll n=x-y;
ll sum=x,ans=1;
ll tmp=h-sum;
if(tmp%n==0) ans+=tmp/n;
else ans+=tmp/n+1;
cout<<ans;
return 0;
}
B题:火力覆盖 贪心+数学
从右端点不断向左枚举,每次找到最靠右的没有被炸弹炸到的点,可以考虑递归
我的代码
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define fi first
#define se second
#define endl '\n'
typedef long long ll;
typedef pair<int,int> PII;
const int mod1 = 1e9 + 7, mod2 = 998244353;
const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
inline int read()
{
int x = 0, f = 1;char ch = getchar();
while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
while (isdigit(ch)) {x = x * 10 + ch - 48; ch = getchar();}
return x * f;
}
const int N=1e6+5;
int n;
int ans[N],vis[N];
int cnt;
stack<int> s;
void find(int n){
if(s.size()==0) return;
int pos=n;
while(double(1.2*pos)>=double(n)) pos--;
pos++;
ans[++cnt]=pos;
//cout<<pos<<endl;
for(int i=ceil(0.8*pos);i<=min(n,int(1.2*pos));i++)
s.pop();
int x=ceil(0.8*pos)-1;
if(x<1) return;
else find(x);
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++) s.push(i);
find(n);
cout<<cnt<<endl;
for(int i=1;i<=cnt;i++) cout<<ans[i]<<" ";
return 0;
}
标程
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;cin>>n;
vector<int> ans;
int r=n;
for(int i=n;i>=0;--i){
if(i*1.2<r){
ans.push_back(i+1);
r=ceil((i+1)*0.8)-1;
}
}
cout<<ans.size()<<endl;
for(int i=0;i<ans.size();++i)cout<<ans[i]<<" ";
cout<<endl;
}
C题:ZZ的函数
待补
D题:自然溢出 思维+数学
刚开始一眼没看出来,于是自己手搓了几组数组发现了规律,当n=66时刚好模数为0
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define fi first
#define se second
#define endl '\n'
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ull;
const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
unsigned long long fac(unsigned long long x){
unsigned long long ans=1;
if(x>=66) return 0;
for(unsigned long long i=1;i<=x;i++){
ans*=i;
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
ull n;
cin>>n;
cout<<fac(n);
return 0;
}
E题:小y的棋子
挖坑待补
F题:小y的镜像串
挖坑待补
G题:飞,比跑快吧
挖坑待补
H题:旋转矩阵 思维+模拟
到了无限sad的题,赛时的思路是发现n数据量很小(n<=4),只需要重点讨论n=4的情况即可,于是考虑用数组存下每一列的最大值,然后遍历所给矩阵找到每个数出现的位置及次数,觉得只有当v[0]==v[1]&&v[2]==v[3]时情况比较特殊,然后开始暴力枚举特殊情况,最后就g了……(不知道哪里错了
正解:因为只有n(n<=4)行,所以会有n个行最大值,即最多有n个有效列(最少有一个即所有最大值都在一列的时候),这时候我们可以对列最大值排序,取出前n大的列再暴力枚举,这样的时间复杂度为O(n^(n+1))可过。
赛时的代码(以为很对,然而只过了10%的数据:
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define fi first
#define se second
#define endl '\n'
typedef long long ll;
typedef pair<int,int> PII;
const int mod1 = 1e9 + 7, mod2 = 998244353;
const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
inline int read()
{
int x = 0, f = 1;char ch = getchar();
while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
while (isdigit(ch)) {x = x * 10 + ch - 48; ch = getchar();}
return x * f;
}
int t;
int a[5][110];
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
cin>>t;
while(t--){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>a[i][j];
}
}
vector<int> mx(m);
mx.clear();
for(int i=0;i<m;i++){
for(int j=0;j<n;j++)
mx[i]=max(mx[i],a[j][i]);
}
vector<int> v;
map<int,vector<PII>> mp;
v.clear();
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(a[j][i]==mx[i]){
v.push_back(mx[i]);
mp[mx[i]].push_back({j,i});
}
}
}
sort(v.begin(),v.end(),greater<int>());
ll ans=0;
if(n<=3){
for(int i=0;i<n;i++) ans+=v[i];
}else {
if(v[0]==v[1]&&v[2]==v[3]){
int ok=0;
vector<int> s1; s1.clear();
set<int> st1; st1.clear();
for(auto x:mp[v[0]]){
s1.push_back(x.fi);
st1.insert(x.se);
}
vector<int> s2; s2.clear();
set<int> st2; st2.clear();
for(auto x:mp[v[2]]){
s2.push_back(x.fi);
st2.insert(x.se);
}
if(s1.size()==2&&s2.size()==2&&st1.size()==1&&st2.size()==1){
if((s1[0]+1==s1[1])||(s1[0]==0&&s1[1]==3)){
if(s2[0]+2==s2[1]) ok=1;
}else {
if((s2[0]+1==s2[1])||(s2[0]==0&&s2[1]==3)) ok=1;
}
}
if(ok==1) ans=v[0]+v[1]+v[2]+v[4];
else ans=v[0]+v[1]+v[2]+v[3];
}
else ans=v[0]+v[1]+v[2]+v[3];
}
cout<<ans<<endl;
}
return 0;
}
标程没看太懂(附上某巨巨好懂的代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
#define int long long
int g[10][200];
tuple<int,int,int>maxv[10];
void solve()
{
memset(maxv,0,sizeof maxv);
int n,m;
cin>>n>>m;
vector<int>q;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>g[i][j],q.push_back(g[i][j]);
sort(q.begin(),q.end(),greater<int>());
if(n<=3||n==4&&q[3]==q[4])
{
int res=0;
for(int i=0;i<n;i++)res+=q[i];
cout<<res<<'\n';
return ;
}
int res=0;
map<int,int>mp;
for(int i=0;i<n;i++)mp[q[i]]=1,res+=q[i];//mp标记前n个最大值
map<int,int>y;
vector<int>x[110];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(mp[g[i][j]])
{
y[j]=1;//y=1表示第j列存在前n个最大值
x[j].push_back(i);//存第j列最大值的行号
}
}
}
if(y.size()==2)//当且仅当只有两列有最大值的情况
{
map<int,int>st;
for(auto [a,b] : y)
{
int xx=x[a][1]-x[a][0];//行号差
st[xx]=1;
}
if(st.count(1)&&st.count(2))res=res-q[3]+q[4];//当且仅当行号差为1和2即此时无论怎么旋转矩阵,总有第二个最大值被第一个最大值挡住,只能往后取q[4]
}
cout<<res<<'\n';
}
signed main()
{
int T;cin>>T;
while(T--)solve();
}
I题:抽卡游戏
挖坑待补
J题:可莉的宝藏
挖坑待补
K题:回文时刻 模拟
比较经典的回文串判定、字符串处理问题
我的极其冗长的代码:
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define fi first
#define se second
#define endl '\n'
typedef long long ll;
typedef pair<int,int> PII;
const int mod1 = 1e9 + 7, mod2 = 998244353;
const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
inline int read()
{
int x = 0, f = 1;char ch = getchar();
while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
while (isdigit(ch)) {x = x * 10 + ch - 48; ch = getchar();}
return x * f;
}
string s;
bool check(string str){
int len=str.size();
int flag=1;
int l=0,r=len-1;
while(l<=r){
if(str[l]==str[r]){
l++;
r--;
}else {
flag=0;
break;
}
}
return flag;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
cin>>s;
string hh=s.substr(0,2);
string mm=s.substr(3,2);
string ss=s.substr(6,2);
//cout<<hh<<mm<<ss;
int a=(hh[0]-'0')*10+hh[1]-'0';
int b=(mm[0]-'0')*10+mm[1]-'0';
int c=(ss[0]-'0')*10+ss[1]-'0';
for(int k=c+1;k<60;k++){
string s="";
if(a<10) s+='0';
s+=to_string(a);
if(b<10) s+='0';
s+=to_string(b);
if(k<10) s+='0';
s+=to_string(k);
if(check(s)){
if(a<10) cout<<'0';
cout<<a<<':';
if(b<10) cout<<'0';
cout<<b<<':';
if(k<10) cout<<'0';
cout<<k;
return 0;
}
}
for(int i=b+1;i<60;i++){
for(int j=0;j<60;j++){
string s="";
if(a<10) s+='0';
s+=to_string(a);
if(i<10) s+='0';
s+=to_string(i);
if(j<10) s+='0';
s+=to_string(j);
if(check(s)){
if(a<10) cout<<'0';
cout<<a<<':';
if(i<10) cout<<'0';
cout<<i<<':';
if(j<10) cout<<'0';
cout<<j;
return 0;
}
}
}
for(int i=(a+1)%24;i<24;i++){
for(int j=0;j<60;j++){
for(int k=0;k<60;k++){
string s="";
if(i<10) s+='0';
s+=to_string(i);
if(j<10) s+='0';
s+=to_string(j);
if(k<10) s+='0';
s+=to_string(k);
if(check(s)){
if(i<10) cout<<'0';
cout<<i<<':';
if(j<10) cout<<'0';
cout<<j<<':';
if(k<10) cout<<'0';
cout<<k;
return 0;
}
}
}
}
return 0;
}
题解十分简洁的代码:
#include<bits/stdc++.h>
using namespace std;
int a,b,c;
bool check1(int x,int y){
int a1=x%10,a2=x/10;
int b1=y%10,b2=y/10;
return a1==b2&&b1==a2;
}
bool check2(int x){
int a1=x%10,a2=x/10;
return a1==a2;
}
int main(){
scanf("%d:%d:%d",&a,&b,&c);
int f=0;
for(int i=0;i<24;i++){
for(int j=0;j<60;j++){
for(int k=0;k<60;k++){
if(check1(i,k)&&check2(j)){
if(i>a||i==a&&j>b||i==a&&j==b&&k>c){
printf("%02d:%02d:%02d\n",i,j,k);
return 0;
}
}
}
}
}
printf("00:00:00\n");
return 0;
}
L题:hs爱矩形 模拟
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define fi first
#define se second
#define endl '\n'
typedef long long ll;
typedef pair<int,int> PII;
const int mod1 = 1e9 + 7, mod2 = 998244353;
const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
inline int read()
{
int x = 0, f = 1;char ch = getchar();
while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
while (isdigit(ch)) {x = x * 10 + ch - 48; ch = getchar();}
return x * f;
}
int x[3],y[3];
map<int,int> mp1,mp2;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
for(int i=1;i<=3;i++){
cin>>x[i]>>y[i];
mp1[x[i]]++;
mp2[y[i]]++;
}
for(auto i:mp1){
if(i.se==1) cout<<i.fi<<" ";
}
for(auto i:mp2){
if(i.se==1) cout<<i.fi;
}
return 0;
}
M题:ZZ的图灵奖
挖坑待补