第一题:0子2023 - 蓝桥云课
dfs搜索+数字转字符串to_string()函数
cpp
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
string s;
string target="2023";
long long mem[7000][5];
string build()
{
string res="";
for(int i=1;i<=2023;i++)
{
res+=to_string(i);
}
return res;
}
long long dfs(int pos,int step)
{
if(step==4)return 1;
if(pos==s.length())return 0;
if(mem[pos][step]!=-1)return mem[pos][step];
long long res=dfs(pos+1,step);
if(s[pos]==target[step])
{
res+=dfs(pos+1,step+1);
}
return mem[pos][step]=res;
}
int main()
{
s=build();
memset(mem,-1,sizeof mem);
long long ans=dfs(0,0);
cout<<ans<<endl;
return 0;
}
第二题:0双子数 - 蓝桥云课
找n=p*p*q*q--->即先找=n-->也就是先找符合条件的n---》再找符合n=p*q(p和q都是质数并且不相等)
cpp
#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
const ll MIN_X = 2333;
const ll MAX_X = 23333333333333LL;
bool isPrime(ll x) {
if (x <= 1) return false;
for (ll i = 2; i * i <= x; i++) {
if (x % i == 0) return false;
}
return true;
}
int main() {
ll max_m = sqrt(MAX_X); // m = p * q 的最大值
ll min_m = ceil(sqrt(MIN_X)); // m 的最小值
// 找出所有不超过 max_m 的质数
vector<ll> primes;
for (ll i = 2; i <= max_m; i++) {
if (isPrime(i)) {
primes.push_back(i);
}
}
ll ans = 0;
int k = primes.size();
for (int i = 0; i < k; i++) {
ll p = primes[i];
if (p * p > max_m) break; // 最小 q > p,所以 p*p 已经超了就不用继续
for (int j = i + 1; j < k; j++) {
ll q = primes[j];
ll m = p * q;
if (m > max_m) break; // 乘积超了,后面的 q 更大,直接退出
if (m >= min_m) {
ans++;
}
}
}
cout << ans << endl;
return 0;
}
第三题:0班级活动 - 蓝桥云课
模拟题--》找规律我们可以发现
cpp
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=100010;
int n;
int a[N];
int cnt[N];
int sum1=0,sum2=0;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
cnt[a[i]]++;
}
for(int i=1;i<=100010;i++)
{
if(cnt[i]>=2)
{
sum1+=(cnt[i]-2);
}
else sum2+=cnt[i];
}
if(sum1>sum2)
{
cout<<sum1<<endl;
}
else cout<<sum1+(sum2-sum1)/2<<endl;
return 0;
}
第四题:0合并数列 - 蓝桥云课
这个题目一看就是用队列
cpp
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=100010;
int n,m;
deque<int> q1,q2;
int ans=0;
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
int a;
cin>>a;
q1.push_back(a);
}
for(int i=0;i<m;i++)
{
int a;
cin>>a;
q2.push_back(a);
}
while(!q1.empty())
{
if(q1.front()==q2.front())
{
q1.pop_front();
q2.pop_front();
}
else if(q1.front()>q2.front())
{
q2[1]+=q2[0];
q2.pop_front();
ans++;
}
else if(q2.front()>q1.front())
{
q1[1]+=q1[0];
q1.pop_front();
ans++;
}
}
cout<<ans<<endl;
return 0;
}
第五题:0数三角 - 蓝桥云课
dfs暴搜,每次从n个点中取三个看看其是否构成等腰三角形(注:三角形面积不能为0)
运行超时(8分版):
cpp
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=2010;
typedef long long ll;
struct node{
ll x,y;
}a[N],path[4];
int ans=0;
int n;
ll dis(ll x1,ll y1,ll x2,ll y2)
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
bool isTriangle(ll x1, ll y1, ll x2, ll y2, ll x3, ll y3) {
return (x2 - x1) * (y3 - y1) != (x3 - x1) * (y2 - y1);
}
bool check()
{
ll x1=dis(path[2].x,path[2].y,path[1].x,path[1].y);
ll x2=dis(path[3].x,path[3].y,path[2].x,path[2].y);
ll x3=dis(path[3].x,path[3].y,path[1].x,path[1].y);
if (!isTriangle(path[1].x, path[1].y,
path[2].x, path[2].y,
path[3].x, path[3].y))
return false;
if(x1==x2||x2==x3||x3==x1)
{
return true;
}
return false;
}
void dfs(int x,int pos)
{
if(x>3)
{
if(check())
{
ans++;
}
return;
}
for(int i=pos;i<=n;i++)
{
path[x].x=a[i].x;
path[x].y=a[i].y;
dfs(x+1,i+1);
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].x>>a[i].y;
}
dfs(1,1);
cout<<ans<<endl;
return 0;
}
第六题:0删边问题 - 蓝桥云课
我用邻接矩阵做的 -.- 只拿了2分,我对图的邻接表开发程度不足1%,我得学学这部分了
我先去进阶一下再来写这个题目
第七题:0AB路线 - 蓝桥云课
又是一记BFS(满分!!!)
这个提的关键就是要判断何时放A何时放B
cpp
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int N=1010;
int n,m,K;
char g[N][N];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,-1,1};
int dist[N][N][11][2];
struct Node {
int x,y,cnt,type;
};
int bfs()
{
queue<Node> q;
memset(dist,-1,sizeof dist);
q.push({1,1,1,0});
dist[1][1][1][0]=0;
while(!q.empty())
{
auto t=q.front();q.pop();
int x=t.x;
int y=t.y;
int cnt=t.cnt;
int type=t.type;
int step=dist[x][y][cnt][type];
if(x==n&&y==m)return step;
char need;
if(cnt<K)
{
need=(type==0)?'A':'B';
}
else need=(type==0)?'B':'A';
for(int k=0;k<4;k++)
{
int nx=x+dx[k];
int ny=y+dy[k];
if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&g[nx][ny]==need)
{
int newcnt,newtype;
if(cnt==K)
{
newtype=1-type;
newcnt=1;
}
else
{
newtype=type;
newcnt=cnt+1;
}
if(dist[nx][ny][newcnt][newtype]==-1)
{
dist[nx][ny][newcnt][newtype] = step + 1;
q.push({nx, ny, newcnt, newtype});
}
}
}
}
return -1;
}
int main()
{
cin>>n>>m>>K;
for(int i=1;i<=n;i++)
{
string s;
cin>>s;
for(int j=1;j<=m;j++)
{
g[i][j]=s[j-1];
}
}
cout<<bfs()<<endl;
return 0;
}
第八题:0抓娃娃 - 蓝桥云课
这个题目很简单我们就可以看出来--》找线段的中点,看中点是否在区间内,中点在则线段在!
我就这样模拟,只拿了4分。超时了哈哈哈
然后想优化----》用前缀和进行优化
cpp
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=2000010;
int n,m;
int a[N];
int sum[N];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
a[x+y]++;
}
for(int i=1;i<=N;i++)
{
sum[i]=sum[i-1]+a[i];
}
for(int i=1;i<=m;i++)
{
int L,R;
cin>>L>>R;
cout<<sum[2*R]-sum[L*2-1]<<endl;
}
return 0;
}
第九题:0拼数字 - 蓝桥云课
暴力dfs枚举--》只拿了1分(运行超时) 就不能多给点分吗
cpp
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1000010;
typedef long long ll;
int n,m;
ll res=0;
void dfs(int x,ll sum,int numa,int numb)
{
if(x>n+m)
{
if(sum%2023==0)
{
res=max(res,sum);
}
return;
}
if(numa<m)
{
dfs(x+1,sum*10+3,numa+1,numb);
}
if(numb<n)
{
dfs(x+1,sum*10+2,numa,numb+1);
}
}
int main()
{
cin>>n>>m;
dfs(1,0,0,0);
cout<<res<<endl;
return 0;
}
第十题:0逃跑 - 蓝桥云课
耐心耗光了不想做了就没做