题目
36进制
题目描述
解题思路
简单题,就是进制转换;但是因为好久没做,第一次把进制当成10处理了。然后测试‘AA’,发现结果不对~~~。
代码展示
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5;
/*
MANY
1040254
*/
int main(){
cout<<('Z'-'A'+10)<<endl;
//int ans=('Y'-'A'+10)*1+('N'-'A'+10)*100+('A'-'A'+10)*1000+('M'-'A'+10)*10000;
int ans=('Y'-'A'+10)*1+('N'-'A'+10)*1*36+('A'-'A'+10)*1*36*36+('M'-'A'+10)*1*36*36*36;
cout<<ans<<endl;
return 0;
}
总结
题目中给出的信息要仔细阅读、充分利用;没有那个‘AA’==370,我一大意都看不出来哪里出错。烦~烦
磁砖样式
题目描述
解题思路
发现环
题目描述
解题思路
1.DFS暴搜n次
- 遍历节点1~n;
- 对于节点x,用DFS(x,x,cnt)进行搜索,表示从x出发,回到x;ans[cnt]表示第cnt步到达的节点;
代码展示
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
vector<int>G[maxn];
int ans[maxn];
bool vis[maxn];
int n;
bool flag;
bool DFS(int s,int x,int cnt){
// cout<<s<<" "<<x<<" "<<cnt<<endl;
ans[cnt]=x;
if(flag)return true;
int l=G[x].size();
vis[x]=1;
for(int i=0;i<l;i++){
if(flag)return true;
int f=G[x][i];
if(f==s){
sort(ans,ans+cnt+1);
for(int i=0;i<=cnt;i++){
if(i!=0)cout<<" ";
cout<<ans[i];
}
cout<<endl;
flag=true;
}
if(!vis[f]){
DFS(s,f,cnt+1);
}
}
return false;
}
int main(){
cin>>n;
int a,b;
for(int i=0;i<n;i++){
cin>>a>>b;
G[a].push_back(b);
}
for(int i=1;i<=n;i++){
memset(vis,0,sizeof(vis));
vis[i]=1;
if(DFS(i,i,0))break;
}
return 0;
}
但是这样计算,无法通过所有的测试点;样例与自测都能通过;暂时还不知道为什么 ~
2.并查集+DFS
- 先用并查集求出这条环上的两点;
- 再用DFS(s,f),搜索s能到达的点,直到s==f;
- 但是有个问题需要解释:
–为什么它能一次就访问到环上的所有点;
代码展示
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5;
/*
1.找出环上的两点(并查集)
2.DFS深搜
=========
总结
1.注意maxn范围,一定+5
2.void的DFS可以没有返回值,但bool类型的一定要有
3.什么时候需要回溯?什么时候不需要回溯
*/
vector<int>G[maxn];
int ans[maxn];
int Fa[maxn];
int vis[maxn];
int cnt;
int Find(int x){
return x==Fa[x] ? x:Fa[x]=Find(Fa[x]);
}
void DFS(int s,int t,int cnt){
vis[s]=1;
ans[cnt]=s;
if(s==t){
sort(ans,ans+cnt+1);
//cout<<cnt<<endl;
for(int i=0;i<=cnt;i++){
if(i!=0)cout<<" ";
cout<<ans[i];
}
return;
}
for(int i=0;i<G[s].size();i++){
int f=G[s][i];
if(!vis[f])
DFS(f,t,cnt+1);
}
}
int main(){
int n;
scanf("%d",&n);
int a,b;
int s,t;
for(int i=1;i<=n;i++)Fa[i]=i;
for(int i=0;i<n;i++){
scanf("%d%d",&a,&b);
int fa=Find(a),fb=Find(b);
if(fa!=fb){
Fa[fa]=fb;
}
else {
s=a,t=b;
}
G[a].push_back(b);
G[b].push_back(a);
}
//cout<<s<<" "<<t<<endl;
DFS(s,t,0);
return 0;
}
对局匹配
题目描述
解题思路
1.数据分组+DP
- 把数据分成每组之间相差为k的k组数据,即{0,k,2k,3k~~~,n*k},;
- 那么不难发现各组数据之前是不会相互匹配的;
- 而对于每一组数据,我们可以当成打家劫舍问题求解,即不能选择相邻的两个数(差为k);
- 所以,最大的在线人数就是各组选择人数之和;
- 复杂度为O(maxn),是个常数;
代码展示
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
/*
1.
10 0
1 4 2 8 5 7 1 4 2 8
10 1
2 1 1 1 1 4 4 3 4 4
====
思路:
1.把数据按照相差k来分组
2.对与每组数据,当作 打家劫舍问题 处理
*/
int num[maxn];
int val[maxn];
int main(){
int n,k;
cin>>n>>k;
int x;
int ans=0;
for(int i=0;i<n;i++){
cin>>x;
if(!num[x])
ans++;
num[x]++;
}
if(k!=0){
ans=0;
for(int i=0;i<k;i++){
int t=0;
for(int j=i;j<=maxn;j+=k){
val[t++]=num[j];
}//生成一组差值为k的数据
int fir=val[0],sec=max(val[0],val[1]);
for(int j=2;j<t;j++){
int temp=max(sec,fir+val[j]);
fir=sec;
sec=temp;
}
ans+=sec;
}
}
cout<<ans<<endl;
return 0;
}
观光铁路
题目描述
解题思路
发