思路:
构造“循环节”
#include
using namespace std;
vectorv;
int n;
int ans(vector v){
vectorve(v);
sort(ve.begin(),ve.end());
mapma;
int n=ve.size(),m=0;
for(int i=0;if(n,false);
for(int i=0;i>n;
int x;
for(int i=0;i>x;
v.push_back(x);
}
cout<
延申——只交换相邻两元素的最小交换数(逆序对数)
#include
using namespace std;
typedef long long ll;
const int N=100010;
int n;
int q[N],tmp[N];
ll merge_sort(int l,int r){
if(l>=r) return 0;
int mid=l+r>>1;
ll sum=merge_sort(l,mid)+merge_sort(mid+1,r);
int num=0,i=l,j=mid+1;
while(i<=mid&&j<=r){
if(q[i]<=q[j]) tmp[num++]=q[i++];
else{
tmp[num++]=q[j++];
sum+=mid-i+1;
}
}
while(i<=mid) tmp[num++]=q[i++];
while(j<=r) tmp[num++]=q[j++];
for(int i=l,j=0;i<=r;i++,j++)
q[i]=tmp[j];
return sum;
}
int main(){
cin>>n;
for(int i=0;i>q[i];
cout<
题解:
对于每个位置h的雕,需要判断它前面的h+1的位置是否有一只雕,如果有,则说明h+1位置的雕可以和当前位置的雕在一支箭上,我们设置每次当前位置的雕数量++,即mp[val]++;,对于在同一支箭上的h+1的雕的数量--,即mp[val+1]--;
#include
using namespace std;
unordered_mapmp;
int n, val, cnt;
signed main (){
// freopen("in", "r", stdin);
scanf("%d", &n);
for (int i = 0;i < n; i++) {
scanf("%d", &val);
if (!i) mp[val]++;
else {
if (mp[val + 1]) mp[val + 1] -= 1;
mp[val] += 1;
}
}
for (auto x : mp) cnt += x.second;
cout << cnt;
return 0;
}
注意:
由于本题数据范围很大,n<=1e6
我们采用unordered_map存储
map对应的数据结构是红黑树。红黑树是一种近似于平衡的二叉查找树,里面的数据是有序的。在红黑树上做查找、插入、删除操作的时间复杂度为O(logN)。——有序
unordered_map对应哈希表,哈希表的特点就是查找效率高,时间复杂度为常数级别O(1), 而额外空间复杂度则要高出许多。所以对于需要高效率查询的情况,使用unordered_map容器,但是unordered_map对于迭代器遍历效率并不高。而如果对内存大小比较敏感或者数据存储要求有序的话,则可以用map容器。——无序
#include
#define int long long
using namespace std;
signed main()
{
//freopen("in","r",stdin);
string s ;
cin >> s ;
int q = 0 , qu = 0 , qua = 0 , quac = 0;
int cnt = 0 ; int flag = 0 ;
int Ans = INT_MAX;
for(int i = 0 ; i < s.length() ; i++){
if(s[i]=='q'){
if(cnt)cnt--;
q++;
}else if(s[i]=='u'){
if(q){q--,qu++;}
else flag = 1;
}else if(s[i]=='a'){
if(qu)qua++,qu--;
else flag = 1;
}else if(s[i]=='c'){
if(qua)quac++,qua--;
else flag = 1;
}else if(s[i]=='k'){
if(quac)quac--,cnt++;
else flag = 1;
}
if(quac==0&&qua==0&&qu==0&&q==0)Ans = min(Ans,cnt),cnt = 0;
}
if(q||qu||qua||quac)flag = 1;
if(flag){ puts("-1");return 0;}
printf("%d\n",Ans);
return 0;
}
双指针做法——加强数据后暴力不能做的情况
#include
using namespace std;
int t, n, k, st[26];
signed main() {
string str;
scanf("%d", &t);
for (int T = 1;T <= t; T++) {
cin >> n >> k >> str;
for (int i = 0; i < 26; i++) st[i] = 0;
int l = 0, r = -1, cnt = 0;
while (r != str.size()-1) {
int x = str[++r] - 'A';
if (r - l > k) st[str[l++] - 'A']--;
if (st[x]) cnt++;
st[x]++;
}
printf("Case %d: %d\n", T, cnt);
}
return 0;
}
字符串模拟
#include
using namespace std;
string mul(string s1, string s2) {
string str = "";
vector a(110);
for (int i = 0; i < s1.size(); i++) {
for (int j = 0; j < s2.size(); j++) {
a[j + i + 1] += ((s1[s1.size() - i - 1] - '0') * (s2[s2.size() - j - 1] - '0'));
}
}
for (int i = 1; i < 100; i++) a[i + 1] += a[i] / 10, a[i] %= 10;
bool f = true;
for (int i = 100; i >= 1; i--) {
if (f && a[i] == 0) continue;
f = false;
str += to_string(a[i]);
}
if (f == true) str += '0';
return str;
}
int cmp(string s1, string s2) { //-1小于,1大于,0等于
if (s1 == s2) return 0;
if (s1.size() < s2.size()) return -1;
if (s2.size() < s1.size()) return 1;
for (int i = 0; i < s1.size(); i++) {
if (s1[i] > s2[i]) return 1;
if (s1[i] < s2[i]) return -1;
}
}
int main() {
string n;
cin >> n;
long long l = 1, r = 10000000000;
while (l < r) {
long long mid = (l + r + 1) / 2;
string mid3 = mul(mul(to_string(mid), to_string(mid)), to_string(mid));
if (cmp(mid3, n) <= 0) l = mid;
else r = mid - 1;
}
cout << r;
return 0;
}