Solution to the problem of the 11th weekly game of acwing

Time:2022-4-25

Calculate ABC

first\(0<=a<=b<=c\)
Will be given at random
\(a+b,a+c,b+c,a+b+c\)Value of

because\(a,b,c\)Are positive integers, so\(a+b+c\)Must be the maximum
Then use\(a+b+c\)Subtract one by one (Note:\(a,b,c\)size

  • code
#include
#include
#include
using namespace std;
int x[5];
int main(){
	for(int i=1;i<=4;++i) cin>>x[i];
	sort(x+1,x+5);
	for(int i=3;i>=1;--i) cout<

Square up

According to the simulation of the meaning of the title, it is not difficult to think of violent enumeration. Each number deleted from the original number is listed
Looking at the data range, the length of the number is the largestTenTherefore, each number can be enumerated 2 ^ 10 times at most, and each enumeration can be enumerated 10 times at most,\(t<=10\)Group data
N is the length of the number
So time complexity\(O(2^n*n*t)\)

  • Concrete implementation
    (DFS and BFS are OK)
    Here is a clever and easy to implement method

Using binary
for instance
Original number\(2081\)
$(1010)_ 2 $1 means that the number of corresponding positions is not deleted, and 0 means that the number of corresponding positions is deleted
According to the above rules, the deleted number is 28
\((0111)_2\)The deleted number is 081, but here you will find that there is a leading 0, but this problem will not occur in the specific implementation, because we convert it into an integer bit by bit, cleverly avoiding the problem of leading 0
Since it is to find at least one deletion operation
That’s the enumeration order\(0-2^n\)

  • code
#include
#include
#include
#include

using namespace std;
string s;
int t;
Int stlen (int x) {// find the number of digits of X
    int ans=0;
    for(;x;++ans) x/=10;return ans;
}
int main(){
    cin>>t;
    while(t--){
        cin>>s;
        int len=s.length();
        int ans=100;
        for(int i=0;i>j & 1)
                    x=x*10+s[j]-'0';
            int sq=sqrt(x);
            if(x && sq*sq==x) ans=min(ans,len-stlen(x));
        }
        if(ans!=100) cout<

Maximize the shortest path

Breakthrough:onlyAndmustelectTwo special points
Then consider three cases
Set two special points as\(x,y\)

  • Yes\(x,y\)But without arbitrary\(x,y\)

  • After two\(x,y\)The shortest path is from\(1——>n\)

  • After two\(x,y\)The shortest path is from\(n——>1\)

set up\(dis1[],dis2[]\)They are the shortest distance from 1 to each point and the shortest distance from n to each point
The answer to each of the three situations is
1.\(dis1[n]\)(it is the shortest circuit without passing through any point)
2.\(dis1[x]+1+dis2[y]\) (1——>x+x——>y+y——n
3.\(dis2[x]+1+dis1[y]\) (n——>x+x——>y+y——1

After finding the maximum value of the latter two cases
In the three cases, take the minimum value (why not take the larger two values, because although the larger two constitute the shortest circuit, when the three cases are discussed together, the two values that are not larger are not the sameconstituteshortest path
That is, after adding an edge, it is likely that the shortest distance will be reduced)

In the first case, just run the shortest circuit
First and second, preprocessing
\(dis1 [] and dis2 [] \), just run the shortest circuit

N is the shortest distance possible

Therefore, the goal now is to find the maximum value of case 2 and 3 and take the minimum value(
If violence demands, go straight to GG
hypothesis\((i,j)\)Is a pair and\(i!=j\), and I, J ∈ is special
Take any pair, and you will get the answer in two or three cases
\(max(min(dis1[i]+1+dis2[j],dis1[j]+dis[i]+1))\)

When dis1 [i] + 1 + dis2 [J] < = dis1 [J] + dis [i] + 1
That is, dis1 [i] – dis2 [i] < = dis [J] – dis2 [J];

Sort pairs by difference
here
When the last pair is x
Take max (dis1 [1 ~ X-1]) + dis2 [x])
X from 1 to K

Take the maximum value of, and finally take the minimum value with dis1 [n]

  • code
#include
#include
#include
#include
#include

using namespace std;
int n,m,k;const int maxn=2e5+10;
int head[maxn*2];
int p[maxn];
int cnt=0;
int dis1[maxn],dis2[maxn];
struct node{
    int v,next;
}e[maxn*2];
void add(int u,int v){
    e[++cnt].v=v;
    e[cnt].next=head[u];
    head[u]=cnt;
}
bool cmp(int a,int b){
    return dis1[a]-dis2[a]  >q;
    q.push(make_pair(-dis[1],st));
    while(!q.empty()){
        int u=q.top().second;q.pop();
        if(vl[u]) continue;
        vl[u]=1;
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].v;
            if(dis[v]>dis[u]+1){
                dis[v]=dis[u]+1;
                q.push(make_pair(-dis[v],v));
            }
        }
    }
}
int main(){
    scanf("%d%d%d",&n,&m,&k);memset(head,0,sizeof(head));
    for(int i=1;i<=k;++i) scanf("%d",&p[i]);
    for(int i=1;i<=m;++i){
        int u,v;scanf("%d%d",&u,&v);
        add(u,v);add(v,u);
    }
    dj(1,dis1);
    dj(n,dis2);
    sort(p+1,p+1+k,cmp);
    int res=0,x=dis1[p[1]];
    for(int i=2;i<=k;++i){
        int t=p[i];
        res=max(res,dis2[t]+x+1);
        x=max(x,dis1[t]);
    }
    printf("%d",min(res,dis1[n]));return 0;
}