# November 15, 2021 (2019 CCPC network trial)

## A - ^&^

Meaning:

t group of samples. Each group of samples gives you an A and B. you need to find a minimum C to make (a)    xor    C)   &   (B    xor    C) The value of is the smallest.

Idea:

em... multiplicative distributive law? Extract A and B, and then operate with (&) in XOR C. because the XOR is the same as 0 and the difference is 1, you want the smallest sure C to be equal to A & B. note here that if the calculated C=0, you want to output 1.

code:

```#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
long long ans;
long long a,b;
cin>>a>>b;
ans=a&b;
if(ans==0)
cout<<1<<endl;
else
cout<<ans<<endl;
}
}```

## F - Shuffle Card

Meaning:

Give you two numbers n and M. you now have n cards from 1 to n. next, you have m operations. Enter a card number for each operation. Next, you need to raise this number to the first place, and the others go back in turn to output the order of cards after M operations.

Idea:

a[i] save the card and mark each number of the a[i] array with vis[i]. M operations can be found. Isn't it the order of this card that you save the b array from back to front? Because it is an operation performed from back to front. Marking its vis[i] as 0 at the beginning means that it has been saved. After you save the card numbers ahead of these m operations (saved vis[i] All are marked as 0), and the rest (i.e. vis[i] is 1) can be stored in turn. Note: when it outputs, there must be a space after each number, and no line feed is allowed. Both pits step on QAQ.

code:

```#include<bits/stdc++.h>
using namespace std;
int a,b,op,vis;
int main()
{
ios::sync_with_stdio(false);
memset(vis,0,sizeof(vis));
long long ans;
int n,m;
cin>>n>>m;
for(int i=1; i<=n; i++)
{
cin>>a[i];
vis[a[i]]=1;
}
for(int i=1; i<=m; i++)
cin>>op[i];
int k=1;
for(int i=m; i>=1; i--)
{
if(vis[op[i]])
{
b[k++]=op[i];
vis[op[i]]=0;
}
}

for(int i=1; i<=n; i++)
{
if(vis[a[i]])
{
b[k++]=a[i];
vis[a[i]]=0;
}
}

for(int i=1; i<=n; i++)
{
cout<<b[i]<<" ";
}

}```

## G - Windows Of CCPC

Meaning:

Enter an n to find the corresponding pattern.

```n=1
CC
PC

n=2
CCCC
PCPC
PPCC
CPPC

n=3
CCCCCCCC
PCPCPCPC
PPCCPPCC
CPPCCPPC
PPPPCCCC
CPCPPCPC
CCPPPPCC
PCCPCPPC```

Idea:

Simulation is to copy the pattern in four copies, and reverse all in the lower left corner (that is, P is C, C is p).

Because n=1 is a second-order matrix, n=2   Is a fourth-order matrix, n=3   Is an eighth order matrix

So the size of each matrix is the n-th power of 2

Assuming that we divide the first-order window into four areas, we can find that the symbols of areas 1, 2 and 4 are the same, and the symbols of the third area and other areas are 'opposite' (C turns into P, P turns into c).
In the case of the second order and above, we can know that it is based on the upper order window. The upper order window is regarded as zone 1, and the relationship between zones is similar to that of the first order. Note that all symbols in zone 3 should be 'opposite' to those in other zones.

The third-order and higher-order windows are similar to the above derivation process.
Because the data of the subject is relatively small, we can directly preprocess it with an array and output it directly at that time. It should be noted that we can find that the size of each order window is the K power of 2 (k is the order). Therefore, the abscissa range of zone 2 is from 2 (k-power-1) + 1 ~ 2 k-power, and the ordinate range is from 1 ~ 2 k-power-1 (bloggers set the initialization starting point as 1). Other areas are similar.

code:

```#include<iostream>
#include<cmath>
using namespace std;
const int MAX = 1024+5;
char mp[MAX][MAX];

int main(void)
{
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
mp = 'C'; //Initialize the original upper left corner
mp = 'C';
mp = 'P';
mp = 'C';

int k = 1;//Order
for(int i=1; i<=n; i++)
{
int x1 = pow(2,k);
int x2 = pow(2,k-1);

for(int i=1; i<=x2; i++) //Upper right corner (take the upper left corner as the reference, i.e. assign the ordinate -x2 position to the current position)
{
for(int j=x2 + 1; j<=x1; j++)
{
mp[i][j] = mp[i][j-x2];
}
}

for(int i=x2 + 1; i<=x1; i++) //Lower right corner (taking the upper right corner as the reference, i.e. the abscissa -x2 position is assigned to the current position)
{
for(int j=x2 + 1; j<=x1; j++)
{
mp[i][j] = mp[i-x2][j];
}
}

for(int i=x2 + 1; i<=x1; i++) //Lower left corner (take the upper left corner as the reference, i.e. the ordinate -x2 position is assigned to the current position by flipping)
{
for(int j=1; j<=x2; j++)
{
if(mp[i-x2][j] == 'C')
{
mp[i][j] = 'P';
}
if(mp[i-x2][j] == 'P')
{
mp[i][j] = 'C';
}
}
}
k++;
}

int x = pow(2,n);
for(int i=1; i<=x; i++)
{
for(int j=1; j<=x; j++)
{
cout << mp[i][j];
}
cout << endl;
}
}
return 0;
}

```

## H - Fishing Master

Meaning:

There are n fish. Each fish needs to be cooked for a corresponding time to eat. The time for catching a fish is the same. You can't do anything else during the fishing time. You can catch multiple fish. Please ask how long it takes to cook all the fish.

Idea:

First of all, the first time we fish and all the time we stew fish should be included in the answer. When we cook fish, we can choose to fish, but we can catch a[i]/k fish at most. At this time, we have a choice: whether to spend K - (a[i]%k) more time to catch one more fish. Think carefully, that is, if we don't lack fish to stew later, we certainly don't need to spend more time, However, in case there is a shortage of fish behind us, we must spend more time. Therefore, we put this time into a priority queue. If we need to cook fish but the number of fish in our hands is not enough, we must go to the front and spend more time changing a fish to take the first place.

Solution: code:

```#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll MAXN = 1e5+5;
ll a[MAXN];

priority_queue<ll,vector<ll>,greater<ll> >q;
bool cmp(ll a,ll b)
{
return a>b;
}

int main()
{
ll t,n,k;
scanf("%lld",&t);
while(t--)
{
while(!q.empty())
q.pop();
scanf("%lld%lld",&n,&k);
for(ll i=1; i<=n; i++)
scanf("%lld",&a[i]);
sort(a+1,a+n+1,cmp);
ll ans=k,num=1;
for(ll i=1; i<=n; i++)
{
ans+=a[i];
if(num>=i)
{
num+=a[i]/k;
q.push(k-(a[i]%k));
continue;
}
if(q.empty())
ans+=k;
else
{
ans+=q.top();
q.pop();
}
num+=a[i]/k;
q.push(k-(a[i]%k));
}
printf("%lld\n",ans);
}
return 0;
}
```

## D - path

Meaning:

Undirected graph, n points, m weighted edges, find the length of the k-th shortest path.

Idea:

bfs, it should be noted that if each reachable point is extended, it will timeout + burst the stack. In fact, it is not necessary to do so. Each time, only the point of the same layer and the smallest point of all edges are extended.

First put all the edges in the queue, and then go out bfs. Take the head of the team every time, then connect a point, plug it back, take the query offline, and then take the head of the team before recording max(k), and you can access O (1).

If the priority queue is simulated directly, the time and space will be blocked by the chrysanthemum. Therefore, an optimization should be added. The priority queue should be changed to set to ensure that there are only max(k) elements in each set

Solution: code:

```#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const ll MAXN = 5e4+5;
const ll MOD = 1e9+7;
struct node
{
ll x,y;
ll val;
bool operator <(const node &r)const
{
return val<r.val;
}
} a,b;
multiset<node>s;
struct nod
{
ll to,val;
} p;
vector<nod>v[MAXN],g[MAXN];
ll ans[MAXN],c[MAXN];
bool cmp(nod a,nod b)
{
return a.val<b.val;
}
int main()
{
ll t,n,m,Q,u,V,w;
scanf("%lld",&t);
while(t--)
{
ll maxx=0;
scanf("%lld%lld%lld",&n,&m,&Q);
s.clear();
for(ll i=1; i<=n; i++)
v[i].clear();
while(m--)
{
scanf("%lld%lld%lld",&u,&V,&w);
p.to=V,p.val=w;
v[u].push_back(p);
a.x=u,a.y=V;
a.val=w;
s.insert(a);
}
for(ll i=1; i<=n; i++)
sort(v[i].begin(),v[i].end(),cmp);
for(ll i=1; i<=Q; i++)
{
scanf("%lld",&c[i]);
maxx=max(maxx,c[i]);
}
ll pos=0;
multiset<node>::iterator it;
while(!s.empty())
{
a=*s.begin();
s.erase(s.begin());
ans[++pos]=a.val;
if(pos==maxx)break;
int len=v[a.y].size();
for(ll i=0; i<=len-1; i++)
{
b=a;
b.y=v[a.y][i].to;
b.val+=v[a.y][i].val;
if(s.size()>maxx-pos)
{
it=s.end();
it--;
if((*it).val>b.val)
{
s.erase(it);
s.insert(b);
}
else break;
}
else
{
s.insert(b);
}
}

}
for(ll i=1; i<=Q; i++)
{
printf("%lld\n",ans[c[i]]);
}
}
return 0;
}
```

Tags: C++

Posted on Wed, 17 Nov 2021 17:04:38 -0500 by erax