题目1483:求最大最小数
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>
#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-8
#define MOD 10009
#define MAXN 10010
#define MAXM 100010
#define INF 99999999
#define ll __int64
#define bug cout<<"here"<<endl
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)
using namespace std;
int Read()
{
char c = getchar();
while (c < '0' || c > '9') c = getchar();
int x = 0;
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x;
}
void Print(int a)
{
if(a>9)
Print(a/10);
putchar(a%10+'0');
}
int main()
{
//fread;
int n;
while(scanf("%d",&n)!=EOF)
{
int mx=-1000010,mi=1000010;
for(int i=0;i<n;i++)
{
int a;
scanf("%d",&a);
mi=min(mi,a);
mx=max(mx,a);
}
printf("%d %d\n",mx,mi);
}
return 0;
}
因为只有13位 每位上只可能是0 1 2三个数字 所以最后就3^13种情况 我们记录下每个字符串对应于初始字符串需要移动的次数 BFS搜索 当前移动次数少的优先
讲当前的字符串转换为对应的3进制数 从而方便标记当前字符串有没有搜索到过
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>
#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-8
#define MOD 10009
#define MAXN 10010
#define MAXM 100010
#define INF 99999999
#define ll __int64
#define bug cout<<"here"<<endl
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)
using namespace std;
int Read()
{
char c = getchar();
while (c < '0' || c > '9') c = getchar();
int x = 0;
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x;
}
void Print(int a)
{
if(a>9)
Print(a/10);
putchar(a%10+'0');
}
int n;
string str;
struct node
{
int step;
string s;
bool operator<(const node p)const
{
return step>p.step;
}
};
int vis[1600000];
priority_queue<node> que;
int judge(string s)
{
for(int i=0;i<n-3;i++)
{
if(s.substr(i,4)=="2012")
return 1;
}
return 0;
}
int getnum(string s)
{
int x=0;
for(int i=0;i<n;i++)
{
x*=3;
x+=s[i]-'0';
}
return x;
}
int main()
{
// fread;
while(scanf("%d",&n)!=EOF)
{
getchar();
cin>>str;
// cout<<"str "<<str<<endl;
while(!que.empty())
que.pop();
memset(vis,0,sizeof vis);
node no;
no.s=str;
no.step=0;
que.push(no);
int flag=0;
while(!que.empty())
{
no=que.top(); que.pop();
if(judge(no.s))
{
flag=1;
printf("%d\n",no.step);
break;
}
for(int i=0;i<n-1;i++)
{
swap(no.s[i],no.s[i+1]);
int num=getnum(no.s);
// cout<<"num "<<num<<endl;
if(!vis[num])
{
vis[num]=1;
node p;
p.s=no.s;
p.step=no.step+1;
// cout<<"step "<<p.step<<endl;
que.push(p);
}
swap(no.s[i],no.s[i+1]);
}
}
if(!flag)
puts("-1");
}
return 0;
}
我第一想法是从高位开始 根据判断该位是1 2 或者大于2来进行计算 比如说在千位如果是3则1 2在千位就会出现2000次 但是如果是2 则1在千位上就会出现1000次 而2在千位上出现的次数此时就会由后面的数字确定
所以这个时候还跟后面的数字有关。。。顿时觉得有点烦。。
其实去仔细的分析 其实也不是很难。。具体的分析过程可以参考编程之美1的个数
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <string>
#include <cmath>
#include <cstdio>
using namespace std;
char ch[110];
int getnum(int s,int t)
{
int x=0;
for(int i=s;i<=t;i++)
{
x=x*10+ch[i]-'0';
x%=20123;
}
return x;
}
int fac(int n)
{
int x=1;
for(int i=0;i<n;i++)
{
x*=10;
x%=20123;
}
return x;
}
int main()
{
while(scanf("%s",ch)!=EOF)
{
int len=strlen(ch);
int sum=0;
for(int i=0;i<len;i++)
{
int high=getnum(0,i-1);
int low=getnum(i+1,len-1);
int p=fac(len-1-i);
if(ch[i]=='0')
{
sum+=(2*high*p)%20123;
}
if(ch[i]=='1')
{
sum+=(2*high*p+low+1)%20123;
}
if(ch[i]=='2')
{
sum+=((2*high+1)*p+low+1)%20123;
}
if(ch[i]>'2')
{
sum+=(2*high+2)*p%20123;
}
sum%=20123;
}
printf("%d\n",sum);
}
return 0;
}