题意:给n种类型的字符串,每一种有三个属性,i,j,k,i是名字,j是方向,k是数量,方向是有left,right,和any,同一名字的left和right或left和any,right和any匹配,对这些类型的每一个进行排列,问最长的无匹配的是有多长
思路:根据题意模拟,我们记录每一个名字的L,R,A有多少,然后取d=L,R的最小,F=L,R的最大,如果d=0,那么就看a的大小,如果a=0,ans+=f,如果f=0,那么就要匹配一个,ff=1,其他情况则ans+=f,最后得到其他的全部的只有一个方向的,与一个两方向都有的,即可
diamond:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
struct node{
int l=0,r=0,a=0;
};
map<string,node>mp;
set<string>s;
int32_t main() {
int n;
cin>>n;
for(int i=1;i<=n;i++){
string s1,s2;
int x;
cin>>s1>>s2>>x;
s.insert(s1);
if(s2=="left"){
mp[s1].l+=x;
}
else if(s2=="right"){
mp[s1].r+=x;
}
else{
mp[s1].a+=x;
}
}
int ans=0;
int ff=0;
for(auto e:s){
int l=mp[e].l;
int r=mp[e].r;
int a=mp[e].a;
int d=min(l,r);
int f=max(l,r);
if(d==0){
if(a==0){
ans+=f;
}
else{
if(f==0){
if(a>1){
ans+=1;
ff=1;
}
else{
ans+=1;
}
}
else{
ans+=f;
ff=1;
}
}
}
else{
ans+=f;
ff=1;
}
}
if(ff==0){
cout<<"impossible"<<endl;
}
else{
cout<<ans+1<<endl;
}
return 0;
}
/*
* a left 0
a right 0
a any 1
*/
题意:交互题,你需要猜测一个长度为1到20的字符串是什么,你每次给出一个字符串,然后都会给你反馈一个程序的运行时间,每个操作消耗多少时间,题目中给了,问你在2500次询问内怎么得到这个字符串
思路:我们最暴力的对每一位的字符都枚举,次数也不大,只有20 * 62,小于2500,我们首先是从长度进行枚举判断,如果程序运行时间一直为5ms,即字符串长度为20,那么我们就加字符串的长度,如果长度为14,即正确,然后其他情况,长度相等时,我们对每一位进行检查,首先每位字符如果相等,会消耗9ms,然后我们可以得到前e-1位是相同的,那么我们对第e位进行枚举,依次进行
diamond:
#include<bits/stdc++.h>
using namespace std;
//#define int long long
string ss="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
int32_t main(){
string s="0";
cout<<s<<endl;
string s1;
while(getline(cin,s1)){
if(s1.length()==20){
s=s+'0';
cout<<s<<endl;
}
else if(s1.length()==14){
return 0;
}
else{
int d=0;
for(int i=15;i<s1.length();i++){
if(s1[i]>='0'&&s1[i]<='9'){
d=d*10+(s1[i]-'0');
}
else {
// cout<<d<<endl;
break;
}
}
//cout<<s1[15]<<" "<<s1[16]<<" "<<d<<endl;
int e=(d-5)/9-1;
int x=ss.find(s[e]);
s[e]=ss[x+1];
cout<<s<<endl;
}
}
}
题意:给n个在地球仪上的经纬度的位置,每次都是从当前走向下一个位置,走的路径是最短的弧线,最后一次是从n走到第1个位置,问走完之后是否都涵盖了所有的经度,经度从$-180<=x<180$。
思路:我们可以发现其实与纬度没啥关系,假如两者的距离是小于180度,那么是从小的走向大的即可,如果是大于180度,那么即是走外围,比如1到150,直接从1-150即可,如果是从1走到-175,正面走是从1到180,然后从-180到-175,总共184,如果我们反着走,先走到0,再走到-175,这样就是176,更短一些,当距离等于180度的时候,我们可以发现相对于球心对称,走的路径是半个最长的圆弧,我们可以直接走到赤道,再从赤道走向对立面即可,因为走到了赤道,所以经过了所有的经度线,当然我们还有一个要注意的,我们如果从1->170->-170->-50->0,虽然我们是走了360个度,但我们发现,从0到1没有被走过,因此有缝隙,这样是NO的,因此我们要* 2之后对两个数之间的数也要进行一个判断,注意正的没有180度,乘2后有359 度,无360度,只有负的才有
diamond:
#include<bits/stdc++.h>
using namespace std;
//#define int long long
int32_t main(){
int n;
cin>>n;
int st=0;
vector<int>q;
for (int i = 0; i <n ; ++i) {
int x,y;
cin>>x>>y;
q.push_back(y);
}
q.push_back(q[0]);
vector<int>vis1(181);
vector<int>vis2(182);
vector<int>st1(366);
vector<int>st2(366);
for (int i = 0; i <n ; ++i) {
// cout<<q[i]<<' '<<q[i+1]<<endl;
if(abs(q[i]-q[i+1])==180){
cout<<"Yes\n";
return 0;
}
if(q[i]*q[i+1]>=0){
int l= min(q[i],q[i+1]);
int r= max(q[i],q[i+1]);
for (int j = l*2; j <=r*2 ; ++j) {
if(j>=0)st1[abs(j)]=1;
else st2[abs(j)]=1;
}
}
else{
int r=max(q[i],q[i+1]);
int l=min(q[i],q[i+1]);
if(r-l<180){
for (int j = 0; j <=r*2 ; ++j) {
st1[j]=1;
}
for (int j = l*2; j <=0 ; ++j) {
st2[-j]=1;
}
}
else{
for (int j = r*2; j <360 ; ++j) {
st1[j]=1;
}
for (int j = -360; j <=l*2 ; ++j) {
st2[-j]=1;
}
}
}
}
for (int i = 1; i <360 ; ++i) {
if(!st1[i]){
double ans=(double)i/2;
cout<<"no ";
::printf("%.1f",ans);
return 0;
}
}
for (int i = -360; i <0 ; ++i) {
if(!st2[-i]){
double ans=(double)i/2;
cout<<"no ";
::printf("%.1f",ans);
return 0;
}
}
cout<<"yes\n";
}
题意:给定一个n片的披萨,每片有一个辣度,当你的耐受力>=a[i]的时候,你才能吃掉这块披萨,当你吃掉时,你的耐受力会提高这些数值,你能够吃的只能是相邻的两个,问你的耐受力初始最小是多少时,才能把这块披萨全部吃掉?
思路:很容易想到二分答案,但我们不晓得第一次该吃哪一块披萨,之间枚举的话是$n^2$的做法,因此这边用以给单调栈来处理,我们可以这样考虑,栈中放的是未被消灭的披萨,由于是环形,我们n* 2处理,这个披萨有两个属性,第一个是吃掉他需要多少耐受度,第二个是获得多少耐受度,假如当前mid=1,数组为 5 3 1 1 1 9,我们枚举到5 和3 的时候都>mid,则加入栈,枚举到1时,我们加入res,然后对栈进行消灭,我们发现无法消灭,那么继续往后走,枚举到第三个1时,发现可以消灭3了,那么就加上3,然后消灭5,枚举到9时,也可以消灭,最后st中无元素,就成功,假如在开头加个12,消灭5之后,我们的值也只有1+1+1+3+5=11,无法消灭12,那么枚举到9发现可以再消灭,假如是12 5 3 1 1 1 12 5 3 1 1 1 1 ,我们枚举到,第二个12时,无法消灭,但如果消灭了12,那么我们就可以消灭从第2个到第7个,因此我们将{12,12+5+3+1+1+1}加入到栈中,然后我们枚举到最后一个1的时候,发现就可以把前面全杀死,整体复杂度就是删了多少个,即为O(N)的,加个二分$n * log(1e13)$的,注意会爆long long,加个__INT128
diamond:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int32_t main(){
int n;
cin>>n;
vector<int>a(1e6+10);
for (int i = 1; i <=n ; ++i) {
cin>>a[i];
a[n+i]=a[i];
}
n<<=1;
auto check=[&](int mid){
__int128 res=mid;
stack<pair<int,int>>st;
for (int i = 1; i <=n ; ++i) {
if(a[i]<=res){
res+=a[i];
while (st.size()&&st.top().first<=res){
res+=st.top().second;
st.pop();
}
}
else{
st.push({a[i],res-mid+a[i]});
res=mid;
}
}
return st.empty();
};
int l=0,r=1e13+10;
int ans;
while (l<=r){
int mid=l+r>>1;
if(check(mid)){
r=mid-1;
ans=mid;
}
else{
l=mid+1;
}
}
cout<<ans<<endl;
}