Atcoder Beginner Contest 198

A-E还蛮简单的,本彩笔就来水水题解
A-Div

#include<bits/stdc++.h>
using namespace std;
 
int main(){
	int n;
  cin>>n;
  cout<<n-1<<endl;
}

B - Palindrome with leading zeros
思路:添几个0看有无满足条件的即可。

#include<bits/stdc++.h>
using namespace std;
 
bool check(string s){
  	int len = s.length();
 	for(int i = 0; i <= len/2; i++){
    	if(s[i] != s[len-1-i]) return false;
    }
  	return true;
}
void solve(){
  	string n;
  	cin>>n;
  	int flag = 0,cnt=0;
  	do{
      if(check(n)){ 
        flag = 1;
        break;
      }
      n = '0'+n;
      cnt++;
    }while(cnt <= 9);
  	if(flag) puts("Yes");
  	else puts("No");
}
 
int main(){
 	solve(); 
}

C - Compass Walking
题目大意: 在二维坐标系上,以0,0为原点,每次能走的长度为r,问走到(x,y)需要至少多少步。
思路:每次能走长度为r的范围实际上就是半径为r的圆上的点,下一步走就是圆上每个点再画个半径为r的圆,这样覆盖了半径[0,2r]圆及内部所有的点,也就是说转化成求到(x,y)的距离再除r向上取整就行了。(特判:如果目标点在第一步半径为r的圆内,一步是走不到的,这时候要两步)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve(){
    ll r,x,y;
    while(cin>>r>>x>>y){
        double dis = sqrt( x*x + y*y );
 
        int ans =  ceil(dis/r);
        if( ans == 1 && dis != r) ans++;
        cout<<ans<<endl;
    }
}
 
int main(){
    solve();
}

D - Send More Money
题目大意: 给你三个字符串s1,s2,s3,对其中的字符进行映射,映射为0~9的数字,映射后的数值 s1–>n1, s2 --> n2, s3–> n3,问是否存在满足 n1+n2 =n3的情况并输出,否则输出UNSOLVABLE。
思路:由于一共只有10个数字可以映射,所以当s1s2s3中的不同字符超过10时就不能构造了。而我们对于0~9的数字进行全排列,读入的字符顺序不变,这样就映射了所有可能。考虑对于不同个数为m个的字符进行映射,其实就是取排列后的前m位进行映射。最后记得判断前导0。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
set<char>s;
vector<int> num;
string n1,n2,n3;
map<char,int> mp;
ll v1,v2,v3;
 
bool check(){
    v1=v2=v3=0;
    if(mp[n1[0]] == 0 || mp[n2[0]] == 0 || mp[n3[0]] == 0) return false;
    for(int i = 0; i < n1.length(); i++){
        v1 = v1*10+mp[n1[i]];
    }
    for(int i = 0; i < n2.length(); i++){
        v2 = v2*10+mp[n2[i]];
    }
    for(int i = 0; i < n3.length(); i++){
        v3 = v3*10+mp[n3[i]];
    }
    if( v1 + v2 == v3 ){
        return true;
    }else{
        return false;
    }
}
void solve(){
    cin>>n1>>n2>>n3;
    vector<char>vec;
    for(int i = 0; i < n1.length(); i++){
        s.insert(n1[i]);
    }
    for(int i = 0; i < n2.length(); i++){
        s.insert(n2[i]);
    }
    for(int i = 0; i < n3.length(); i++){
        s.insert(n3[i]);
    }
    if( s.size() > 10 ){
        puts("UNSOLVABLE");
    }else{
        for(auto it : s){
            vec.push_back(it);
        }
        sort(vec.begin(),vec.end());
        ll val = 1;
        for(int i = 1; i <= 10; i++) val*=i;
        for(int i = 0; i < 10; i++){
            num.push_back(i);
        }
        int cnt = 0; bool flag = false;
        while( cnt <= val ){
            cnt++;
            mp.clear();
            for(int i = 0; i < vec.size(); i++){
                mp[vec[i]] = num[i];
            }
            if(check()){
                flag = true;
                break;
            }
            next_permutation(num.begin(),num.end());
          }
        if( flag ){
            cout<<v1<<endl;
            cout<<v2<<endl;
            cout<<v3<<endl;
        }else{
            puts("UNSOLVABLE");
        }
    }
 
}
 
int main(){
    solve();
}

E - Unique Color
题目大意:这是一棵树,节点编号1~N,每个节点有值Ci。定义一个节点x是好节点:从节点1到节点x上没有与x值重复的节点。升序输出所有好节点的编号。
思路:令1为树的根,习惯性考虑DFS。用map记录访问到当前节点各C值出现的次数。考虑同一个节点的子节点,他们在父节点下是毫不相干的,L这个子节点访问后,我们希望父节点到L子节点的数值记录消去,为了不影响遍历父节点的其他子节点,这个时候就可以回溯写啦。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;

int n;
int c[maxn],cnt,head[maxn];
map<int,int> mp;
vector<int> ans;
struct Edge{
    int v,next;
}edge[maxn<<1];

void add(int u,int v){
    edge[cnt].v=v;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}

void init(){
    cnt = 0;
    memset(head,-1,sizeof(head));
    ans.clear();
    mp.clear();
}

void dfs(int now, int pre){
    // mp[c[now]]++;
    for(int i = head[now]; ~i; i = edge[i].next){
        int v = edge[i].v;
        if( v == pre ) continue;
        mp[c[v]]++;
        if(mp[c[v]] == 1)
            ans.push_back(v);
        dfs(v,now);
        mp[c[v]]--;
    }
}
void solve(){
    cin>>n;
    for(int i = 1; i <= n; i++) cin>>c[i];
    int a,b;
    init();
    for(int i = 1; i <= n-1; i++){
        cin>>a>>b;
        add(a,b);
        add(b,a);
    }
    mp[c[1]]++;
    ans.push_back(1);
    dfs(1,0);
    sort(ans.begin(),ans.end());
    for(int i = 0; i < ans.size(); i++){
        cout<<ans[i]<<endl;
    }
}

int main(){
    solve();
}

F题不会QWQ

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值