Now we are in a confusing { } intermediate state, sometimes with line breaks and sometimes without line breaks...
Line breaks do look cleaner. But it looks more complete without line breaks. No wonder those who learn C are arguing about this issue.
Doing the required questions first means grasping the main contradiction
A - Link/Cut Tree
Question description
Reference Code
#include<iostream>
#include<cmath>
using namespace std;
#define ll long long
ll getAns(ll k,ll p){
ll ans=1;
for(int i=1;i<=p;i++)
ans*=k;
return ans;
}
int main()
{
ll l,r,k,p;
while(cin>>l>>r>>k)
{
p=0;
bool legal=false;
while(true){
if(pow(k,p)>r)
break;
if( pow(k,p)>=l && pow(k,p)<=r ){
cout<<getAns(k,p)<<" ";
legal=true;
}
p++;
}
if(!legal)
cout<<-1<<endl;
}
}
Code explanation
The beauty
I think the first clever point is #define ll long long. After all, long long is too long to write.
The second one looks stupid, but in fact the clever thing is to use a separate function to calculate the ans value.
Two easy pitfalls
1. You cannot directly output the result of pow, because it will be expressed in scientific notation.
cout<<pow(k,p)<<" ";
2. You cannot multiply first and then look at the symbol, which does not meet the conditions. ans *= k also exceeds long long!
C - Maximum Product
Question description
Reference Code
#include<iostream>
#include<cmath>
using namespace std;
#define ll long long
int main(){
int n;
int ncase=0;
while(cin>>n){
ll ans=0;
ll num[100];
for(int i=0;i<n;i++){
cin>>num[i];
}
for(int i=0;i<n;i++)
{
for(int j=0;i+j<n;j++){
ll tmp=1;
for(int k=0;k<=j;k++)
tmp*=num[i+k];
if(tmp>ans)
ans=tmp;
}
}
if(ans<0)
ans=0;
printf("Case #%d: The maximum product is %lld.\n\n",++ncase,ans);
}
}
Code explanation
The core are two for loops that traverse possible intervals.
for(int j=0;i+j<n;j++) is quite good, especially i+j<n, which ensures that j is after i and everything can be traversed.
Another wonderful thing is that if(ans<0) ans=0; directly solves all possible negative value situations at the end, without modifying the intermediate algorithm to add some judgments.
E - combined output
Question description
Reference Code
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
using namespace std;
bool cmp(vector<int> a,vector<int> b){
for(int i=0;i<a.size();i++)
{
if(a[i]!=b[i])// 这一步不可少
return a[i]<b[i];
}
}
int main(){
int n,r;
cin>>n>>r;
vector<vector<int> > res;
for(int i=0;i<(1<<n);i++){
int cnt=0;
for(int j=0;j<=n;j++){
if(i&(1<<j)) {
cnt++;
cout << "i:" << i << endl;
cout << "1<<j:" << (1 << j) << endl;
cout<<"cnt:"<<cnt<<endl;
}
}
if(cnt==r){
vector<int> tmp;
for(int j=0;j<=n;j++){
if(i&(1<<j)){
tmp.push_back(j+1);
}
}
res.push_back(tmp);
}
}
sort(res.begin(),res.end(),cmp);
for(vector<int> a : res){
for(int b : a){
cout<<setw(3)<<b;
}
cout<<endl;
}
}
Code explanation
This is really a clever application of bitwise operations.
Let's say the input is 5 3.
To choose 3 means to choose three different numbers among five numbers. In the binary system, there must be three ones among the five digits.
Traversing 2^n, for a specific i, such as 7, it is 01011. At this time, j is traversed from 0 to n-1, which means converting i into binary and scanning each bit. If the bit is 1, let cnt+1.
If cnt=r, it means that the number corresponding to i is exactly the selected r number of digits.
At this time, put the answer into a temporary array, and tmp.push_back(j+1) changes the index from 0 to 1.
There will be C(n,r) answers in the end.
i&(1<<j)
i&(1<<j)
is a bit operation that checks whether bit of an integer i
is 1. This kind of operation is common in algorithms related to combination, subset generation, or other bit operations. j
We use the bitwise operator &
(AND operation) to perform this check. In this operation, we shift the number 1
to the left by j
places, thereby creating a 1 that only has j
Number (other bits are all 0). We then use &
to compare this number with i
and if the result is not 0, it means i
's The a>j
bit is 1, otherwise the bit is 0.
Let's illustrate with some examples:
-
Check the th digit of the number
i = 5
(counting from 0, the second digit):1
- First, we know that
5
is represented in binary as101
. - Using the operation
1<<1
, we shift the number1
to the left by one position to get10
, that is, < a i=4>.2
- Currently, I am the commander
5
(immediately101
) given2
(immediately010
) Progress&
Calculation, Gain0
. This meaning number5
number1
rank 0.
- First, we know that
-
Check the th digit of the number
i = 5
(counting from 0, the third digit):2
- First, we know that
5
is represented in binary as101
. - Using the operation
1<<2
, we shift the number1
to the left by two places to get100
, that is, < a i=4>.4
- Currently, I am the commander
5
(immediately101
) given4
(immediately100
) Progress&
Calculation, Gain4
. This is not0
, so the number5
is the first2
and the rank is 1.
- First, we know that