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