@@ -1870,19 +1870,327 @@ for i in range(0,500+1,50):
18701870 print(res[i:i+50])
18711871```
18721872
1873- ### 12. [ P1249] ( https://www.luogu.com.cn/problem/P1249 )
1873+ ### 12. [ P1249 最大乘积 ] ( https://www.luogu.com.cn/problem/P1249 )
18741874
1875- ### 13. [ P1012 ] ( https://www.luogu.com.cn/problem/P1012 )
1875+ 思路:高精度用 ` Python ` ,要想乘积大那么就要让数字均匀从 ` 2+3+4+5+... ` ,然后剩余值再从后向前匀,有个特殊情况就是剩余的数对于最后的数,那么我们就要给最后的数 ` +2 ` ,剩下的数还是 ` +1 ` ,比如: ` 2+3->8 ` 余 ` 3 ` 但是只有两个数,所以我们必须把后面的 ` 3+2 ` ,然后 ` 2+1 ` ,最后得到 ` 3+5=8 ` 。还有就是 ` 2+3=5 ` 所以 ` 4 ` 以内直接输出本身即可
18761876
1877- ### 14. [ P1923] ( https://www.luogu.com.cn/problem/P1923 )
1877+ ``` python
1878+ import math
1879+
1880+ n = int (input ())
1881+
1882+ if n <= 4 :
1883+ print (n)
1884+ print (n)
1885+ exit ()
1886+
1887+ parts = []
1888+ current = 2
1889+ remaining = n
1890+
1891+ while remaining >= current:
1892+ parts.append(current)
1893+ remaining -= current
1894+ current += 1
1895+
1896+ if remaining > 0 :
1897+ if remaining == parts[- 1 ]:
1898+ parts[- 1 ] += 1
1899+ remaining -= 1
1900+
1901+ for i in range (len (parts)- 1 , - 1 , - 1 ):
1902+ if remaining <= 0 :
1903+ break
1904+ parts[i] += 1
1905+ remaining -= 1
1906+
1907+
1908+ product = 1
1909+ for num in parts:
1910+ product *= num
1911+
1912+
1913+ print (" " .join(map (str , parts)))
1914+ print (product)
1915+ ```
18781916
1879- ### 15 . [ P1116 ] ( https://www.luogu.com.cn/problem/P1116 )
1917+ ### 13 . [ P1012 拼数 ] ( https://www.luogu.com.cn/problem/P1012 )
18801918
1881- ### 16. [ P1068] ( https://www.luogu.com.cn/problem/P1068 )
1919+ 思路:我们把数存进字符串数组,然后以` a+b>b+a ` 比较,这样两数合并产生更大结果的数会被排序到前面,字符串长度一样的时候按照字典序比较,和正常比较数的结果是一样的,然后我们把排序结果直接输出就可以得到最大的数
1920+
1921+ ``` cpp
1922+ #include < bits/stdc++.h>
1923+
1924+ using namespace std ;
1925+ using ll = long long ;
1926+
1927+ int main ()
1928+ {
1929+ int n;
1930+ cin >> n;
1931+ vector<string> nums(n);
1932+ for (auto& s:nums)
1933+ {
1934+ cin >> s;
1935+ }
1936+
1937+ sort (nums.begin(),nums.end(),
1938+ [ ] (string a,string b)
1939+ {
1940+ return a+b>b+a;
1941+ });
1942+
1943+ for (auto& s: nums )
1944+ {
1945+ cout << s;
1946+ }
1947+ }
1948+ ```
1949+
1950+ ### 14. [ P1923 求第 k 小的数] ( https://www.luogu.com.cn/problem/P1923 )
1951+
1952+ 思路:直接用` nth_element ` ,我们不是算法竞赛,能快就快.jpg,注意nth_element是一种排序方法,它保证指定位置左边一定小右边一定大,而且不保证顺序,比一般排序快,我们要获取第k大(从0计)的可以用` *(nums.begin()+k) ` 或者` nums[k] ` ,使用迭代器读取的时候别忘记加括号再解引用,不然会变成` *(nums.begin())+k ` ,注意这题输入量很大,所以要用` ios_base::sync_with_stdio(0) ` 和` cin.tie(nullptr) ` 来加速读取
1953+
1954+ ``` cpp
1955+ #include < bits/stdc++.h>
1956+
1957+ using namespace std ;
1958+ using ll = long long ;
1959+
1960+ int main ()
1961+ {
1962+ ios_base::sync_with_stdio (0);
1963+ cin.tie(nullptr);
1964+
1965+ int n,k;
1966+ cin >> n >> k;
1967+ vector<ll > nums(n);
1968+ for (auto& i: nums )
1969+ {
1970+ cin >> i;
1971+ }
1972+ nth_element(nums.begin(),nums.begin()+k,nums.end());
1973+ cout << * (nums.begin()+k);
1974+
1975+ }
1976+ ```
1977+
1978+ ### 15. [ P1116 车厢重组] ( https://www.luogu.com.cn/problem/P1116 )
1979+
1980+ 思路:仔细读一下题目,发现和冒泡排序的原理一模一样,所以这题其实问的是冒泡排序要交换几次,考的是基本功
1981+
1982+ ``` cpp
1983+ #include < bits/stdc++.h>
1984+
1985+ using namespace std ;
1986+ using ll = long long ;
1987+
1988+ int main ()
1989+ {
1990+ int n;
1991+ cin >> n;
1992+ vector<int> nums(n);
1993+ for (auto& i:nums)
1994+ {
1995+ cin >> i;
1996+ }
1997+
1998+ int res=0;
1999+ for (int i=0;i<n-1;i++)
2000+ {
2001+ for (int j=0;j<n-1-i;j++)
2002+ {
2003+ if (nums[j]>nums[j+1])
2004+ {
2005+ swap (nums[ j] ,nums[ j+1] );
2006+ res++;
2007+ }
2008+ }
2009+ }
2010+ cout << res;
2011+ }
2012+ ```
2013+
2014+ ### 16. [ P1068 分数线划定] ( https://www.luogu.com.cn/problem/P1068 )
2015+
2016+ 思路:先把参与者按照分数和ID排序,然后按照排名找到分数线,输出大于等于分数线的参与者
2017+
2018+ ``` cpp
2019+ #include < bits/stdc++.h>
2020+
2021+ using namespace std ;
2022+ using ll = long long ;
2023+
2024+ struct Att
2025+ {
2026+ int id;
2027+ int score;
2028+ };
2029+
2030+ int main ()
2031+ {
2032+ int n,m;
2033+ cin >> n >> m;
2034+ vector<Att> atts(n);
2035+ for (auto& i:atts)
2036+ {
2037+ cin >> i.id >> i.score;
2038+ }
2039+
2040+ sort (atts.begin(),atts.end(),
2041+ [ ] (Att& a,Att& b)
2042+ {
2043+ if (a.score!=b.score)
2044+ {
2045+ return a.score>b.score;
2046+ }
2047+ return a.id<b.id;
2048+ });
2049+
2050+ int pass_rank=floor(m* 1.5);
2051+ int pass_score=atts[ pass_rank-1] .score;
2052+ int res=0;
2053+ for (auto &i: atts )
2054+ {
2055+ if (i.score<pass_score) break;
2056+ res++;
2057+ }
2058+
2059+ cout << pass_score << " " << res << '\n';
2060+ for (auto &i: atts )
2061+ {
2062+ if (i.score<pass_score) break;
2063+ printf("%04d %d\n",i.id,i.score);
2064+ }
2065+ }
2066+ ```
18822067
18832068### 17. [ P1706] ( https://www.luogu.com.cn/problem/P1706 )
18842069
1885- ### 18. [ P2249] ( https://www.luogu.com.cn/problem/P2249 )
2070+ 思路1:用递归遍历所有位置的排列,使用` used ` 集合来标记每个使用过的数字
2071+
2072+ ``` cpp
2073+ #include < bits/stdc++.h>
2074+
2075+ using namespace std ;
2076+ using ll = long long ;
2077+
2078+ int n;
2079+ void dfs (int start,vector<int > nums,unordered_set<int > used)
2080+ {
2081+ if (nums.size()==n)
2082+ {
2083+ for (auto& i: nums )
2084+ {
2085+ printf("%5d",i);
2086+ }
2087+ cout << '\n';
2088+ return;
2089+ }
2090+
2091+ for (int i=1;i<=n;i++)
2092+ {
2093+ if (used.count(i)) continue;
2094+
2095+ nums.push_back(i);
2096+ used.insert(i);
2097+ dfs(i+1,nums,used);
2098+ used.erase(i);
2099+ nums.pop_back();
2100+ }
2101+
2102+ }
2103+
2104+ int main()
2105+ {
2106+ cin >> n;
2107+ vector<int > nums;
2108+ unordered_set<int > used;
2109+ dfs(1,nums,used);
2110+ }
2111+ ```
2112+
2113+ 思路2:使用`next_permutaion`输出所有组合,注意,`next_permutation`只能输出排序过的组合,按照字典序排列,没有排序过的话输出的组合会不完整
2114+
2115+ ```cpp
2116+ #include <bits/stdc++.h>
2117+
2118+ using namespace std;
2119+ using ll = long long;
2120+
2121+
2122+ int main()
2123+ {
2124+ int n;
2125+ cin >> n;
2126+ vector<int> nums(n);
2127+ for (int i=1;i<=n;i++)
2128+ {
2129+ nums[i-1]=i;
2130+ }
2131+
2132+ do
2133+ {
2134+ for (auto& i:nums)
2135+ {
2136+ printf("%5d",i);
2137+ }
2138+ cout << '\n';
2139+ } while (next_permutation(nums.begin(),nums.end()));
2140+
2141+ }
2142+ ```
2143+
2144+ ### 18. [ P2249 查找] ( https://www.luogu.com.cn/problem/P2249 )
2145+
2146+ 思路:用二分查找` lower_bound ` ,注意使用这个方法必须是排过序的,返回值是第一个大于等于所给数的迭代器
2147+
2148+ | 方法| 作用| 返回值|
2149+ | :--:| :--:| :--:|
2150+ | binary_search| 查找元素是否存在| bool(是否存在)|
2151+ | lower_bound| 第一个大于等于所给数的位置| 迭代器|
2152+ | upper_bound| 第一个大于所给数的位置| 迭代器|
2153+
2154+ > ` upper_bound - lower_bound ` 还可以查找元素出现次数
2155+
2156+ ``` cpp
2157+ #include < bits/stdc++.h>
2158+
2159+ using namespace std ;
2160+ using ll = long long ;
2161+
2162+
2163+ int main ()
2164+ {
2165+ ios_base::sync_with_stdio (0);
2166+ cin.tie(nullptr);
2167+
2168+ int m,q;
2169+ cin >> m >> q;
2170+ vector<int > nums(m);
2171+ for (auto& i: nums )
2172+ {
2173+ cin >> i;
2174+ }
2175+ sort(nums.begin(),nums.end());
2176+ string sep;
2177+ while (q--)
2178+ {
2179+ int k;
2180+ cin >> k;
2181+ auto it=lower_bound(nums.begin(),nums.end(),k);
2182+ if (it==nums.end()||* it!=k)
2183+ {
2184+ cout << sep << -1;
2185+ }
2186+ else
2187+ {
2188+ cout << sep << it-nums.begin()+1;
2189+ }
2190+ sep=" ";
2191+ }
2192+ }
2193+ ```
18862194
18872195## 真题
18882196
0 commit comments