A
关键思路是求每个十进制数的数字以及怎么在一个数组中让判断所有的数字次数相等。
求每个十进制的数字
while(n!=0){
int x = n%10;//x获取了n的每一个位数字
n/=10;
}
扩展:求二进制的每位数字 (注意:进制转换、1的个数、位运算)
x >> k & 1//k代表第几个位置
判断几个数中的数字次数相等
下面是判断3个数中的数字次数相等
bool swap(int n,int i,int j){
int a[]={0,0,0,0,0,0,0,0,0,0};
while(n!=0){
int x = n%10;
a[x]++;
n/=10;
}
while(i!=0){
int x = i%10;
a[x]--;
i/=10;
}
while(j!=0){
int x = j%10;
a[x]--;
j/=10;
}
for(int i=0;i<=9;i++){
if(a[i]!=0){
return false;
}
}
return true;
}
完整代码:
#include <iostream>
#include <cmath>
using namespace std;
bool swap(int n,int i,int j){
int a[]={0,0,0,0,0,0,0,0,0,0};
while(n!=0){
int x = n%10;
a[x]++;
n/=10;
}
while(i!=0){
int x = i%10;
a[x]--;
i/=10;
}
while(j!=0){
int x = j%10;
a[x]--;
j/=10;
}
for(int i=0;i<=9;i++){
if(a[i]!=0){
return false;
}
}
return true;
}
bool is(int n){
for(int i=2;i<=sqrt(n)+1;i++){
if(n%i==0){
int j = n/i;
if(swap(n,i,j)){
return true;
}
}
}
return false;
}
int main(){
int sum=0;
for(int i=1;i<=1000000;i++){
if(is(i)){
sum++;
}
}
cout << sum << endl;
return 0;
}
B
爆搜
#include <bits/stdc++.h>
using namespace std;
int a[][20]={
{1,1,0,1,0,1,1,1,1,1},
{1,1,1,0,0,1,1,1,1,0},
{1,1,0,0,1,0,1,1,1,1},
{1,0,1,1,0,1,1,1,1,0},
{1,0,1,0,1,1,1,1,0,0},
{1,0,0,1,0,1,0,1,0,1},
{1,1,1,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,1,1,0},
{0,1,1,0,1,0,1,1,1,1},
{1,0,1,0,0,1,0,1,0,0},
};
map<int, int> mp;
int ans;
int main(){
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
if(a[i][j]==0){
continue;
}
for(int k=i+1;k<10;k++){
for(int p=0;p<=j;p++){
if(a[k][p]==0){
continue;
}
if (a[k + j - p][p + k - i] == 1 && a[i + j - p][j + k - i] == 1){
int len = (j - p) * (j - p) + (k - i) * (k - i);
if (mp[len] == 0) {
ans++;
mp[len] = 1;
}
}
}
}
}
}
cout << ans;
return 0;
}
扩展map的用法
map容器是一个键值对key—value的映射,其内部实现是一颗以key为关键吗的红黑树。map的key和value可以是任意类型,其中key必须定义小于号运算符。
map的声明
map<key_type,value_type> name;
//列子
map<int int> mp;
map<string,int> mp;
方法
size/empty/clear/begin/end/insert/erase/find/[]
C
求每个数的位的数字。详细见A题。注意数据范围
#include <iostream>
#include <algorithm>
using namespace std;
long long n,sum;
int main(){
cin >> n;
while(n>0){
long long x=n;
while(x!=0){
int aa=x%10;
n-=aa;
x/=10;
}
sum++;
}
cout << sum <<endl;
return 0;
}
D
**最初思路:**遍历从L到R,但是如果随机遍历每个L到R中的每个数,最后得到的最小移动数是不一样。即行不通。
解题思路:
分三种情况:
- 当n<l时。不用移动,输出0.
- 当n>=l&&n<=r时。即考虑移动l-1的步数和移动到r右边的符合条件之间的最小数。
- 当n>r时。即往左右移动找符合最小移动的步数。
完整代码
#include <bits/stdc++.h>
using namespace std;
long long n,l,r;
long long ans;
bool check(int x){
for(int i=1;i<=sqrt(x);i++){
if(x%i==0){
int t = x/i;
if(i>=l && i<=r){
return true;
}
if(t>=l && t<=r){
return true;
}
}
}
return false;
}
int main(){
cin >> n >> l >> r;
if(n<l){
cout << 0 << endl;
return 0;
}
if(n>=l&&n<=r){
ans = n-(l-1);
for(int i=1;i<=2000;i++){
if(!check(r+i)){
ans = min(r+i-n,ans);
break;
}
}
cout << ans <<endl;
return 0;
}
for(int i=1;i<=2000;i++){
if(!check(n+i) || !check(n-i)){
cout << i << endl;
return 0;
}
}
return 0;
}
//5/29完工