题目简要:给出火柴棒的根数,问拼出数字的最大最小值
解答:
火柴棒拼数字1 2 3 4 5 6 7 8 9 0
需要火柴棒 2 5 5 4 5 6 3 7 6 6
对于最大值,我们首先要保证最多的位数,即尽可能多的摆1(因为它需要的火柴棒数2最小),对于n%2==1的情况,我们只需将最高位改为7(需要3根)。
对于最小值,我们同样首先需要保证最小的位数,即尽可能的摆8(需要7根)。对于余下不同火柴棒的情况:
n%7==1
将最高位8换为10
n%7==2
在最高位前添加1
n%7==3
(1)n==3 最高位前添加7
(2)n==10 最高位8变为22
(3)n==17 最高位88变为200
n%7==4
(1)n==4 最高位前添加4
(2)n==11 最高位8变为20
n%7==5
最高位前添加2
n%7==6
最高位前添加6
附代码:
#include
#include
#include
#include
using namespace std;
//2,5,5,4,5,6,3,7,6,6;
void findmax(int x)
{
int m=x;
if(m&1)putchar('7'),m-=3;
for(;m;m-=2)putchar('1');
putchar(' ');
return;
}
void findmin(int x)
{
int m=x;
switch(m%7)
{
case 1:
putchar('1'),putchar('0');
m-=8;
break;
case 2:
putchar('1');
m-=2;
break;
case 3:
if(m==3)
{
putchar('7');
m-=3;
}
else if(m==10)
{
putchar('2'),putchar('2');
m-=10;
}
else
{
putchar('2'),putchar('0'),putchar('0');
m-=17;
}
break;
case 4:
if(m==4)
{
putchar('4');
m-=4;
}
else
{
putchar('2'),putchar('0');
m-=11;
}
break;
case 5:
putchar('2');
m-=5;
break;
case 6:
putchar('6');
m-=6;
break;
}
for(;m;m-=7)putchar('8');
putchar(10);
return;
}
int main()
{
int T,x;
scanf("%d",&T);
while(T--)
{
scanf("%d",&x);
findmax(x);
findmin(x);
}
return 0;
}
未完待续。。。
题解也看不懂怎么破。。好吧,我们来看第三题
其实不是完全搞懂了。有时间再做一遍。
吐槽一下,名字起的这么雷人真的好吗,剧情这么假真的好吗。。。
题目简要:给出一个无向图,每条边正向,反向需要的时间不同(这不就是有向图吗。。),且一条路只能通过一回,问从1回到1需要的最短时间。
题目解析:看完题目我的第一想法是建立一个新点当作终点,它的入/出度与1完全相同,但YY了一下发现很难保证每条边只走一遍。于是就跑去看题解啦。
题解是这样的,思路其实也是建立新点,但构图非常不同。
首先要跑一遍spfa,求出每一个点到1的最短距离dis[i],并记录prev[i]表示这条路径上与1相连的点的标号。然后——>注意前方高能。
枚举图中每一条边
(1)当prev[x]!=x说明从1到x的最短路并没有经过这条边,故在新图中建立一条从起点到终点的边,边权为value+dis[u]
(2)当prev[x]==x即不能再走该边,在新图中建立从x到终点的边,边权为value.
(1)当prev[x]=x,说明原图中即存在这样的最短边
(2)当prev[x]!=x,说明原点到达v的最短路径不是改边,故在新图中建立从1到x的边,边权为value.
(1)当prev[u]!=prev[v],说明原点到达两端点的最短路径是不同的,即存在一条从1到v,边权为dis[u]+value.
(2)当prev[u]==prev[v],在新图中保留原边。
最后在新图中求一次从1到n+1的最短路。
贴代码:
#include
#include
#include
#include
#include
#define maxn 50048
#define maxm 100003
using namespace std;
struct node{
int to,from,val,next;
};
node e[maxm*2],en[maxn*2];
int head[maxn];
int dis[maxn];
int prev[maxn];
bool vis[maxn];
int tot,totn;
int n,m;
void add(int x,int y,int u)
{
e[++tot].to=y;
e[tot].from=x;
e[tot].val=u;
e[tot].next=head[x];
head[x]=tot;
}
void newadd(int x,int y,int u)
{
en[++totn].to=y;
en[totn].from=x;
en[totn].val=u;
en[totn].next=head[x];
head[x]=totn;
}
void spfa()
{
memset(dis,0x7f7f7f7f,sizeof(dis));
memset(vis,0,sizeof(vis));
queue<int> Q;
Q.push(1);vis[1]=1;dis[1]=0;
while(Q.size())
{
int p=Q.front();Q.pop();
vis[p]=0;
for(int k=head[p];k;k=e[k].next)
{
int v=e[k].to;
if(dis[v]>dis[p]+e[k].val)
{
dis[v]=dis[p]+e[k].val;
if(p==1) prev[v]=v;
else prev[v]=prev[p];
if(!vis[v])vis[v]=true,Q.push(v);
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
tot=0;
int u,v,w,y;
memset(head,0,sizeof(head));
for(int i=0;iscanf("%d%d%d%d",&u,&v,&w,&y);
add(u,v,w);
add(v,u,y);
}
spfa();
//½¨Á¢ÐÂͼ
totn=0;
for(int i=1;i<=n;i++)
for(int k=head[i];k;k=e[k].next)
{
if(e[k].to==1)
{
if(prev[i]==i)newadd(i,n+1,e[k].val);
else newadd(1,n+1,e[k].val+dis[i]);
}
else if(i==1)
{
int v=e[k].to;
if(prev[v]==v)continue;
newadd(1,v,e[k].val);
}
else
{
int v=e[k].to;
if(prev[i]==prev[v])newadd(i,v,e[k].val);
else newadd(1,v,dis[i]+e[k].val);
}
}
//ÔÚÔͼÉÏÖØй¹½¨ÐÂͼ£¬ÖØÐÂÀûÓÃspfa()º¯Êý
tot=0;
memset(head,0,sizeof(head));
for(int i=1;i<=totn;i++)
{
int pu=en[i].to;
int pv=en[i].from;
int pw=en[i].val;
add(pv,pu,pw);
}
spfa();
int ans=dis[n+1];
if(ans==0x7f7f7f7f)ans=-1;
printf("%d\n",ans);
return 0;
}