目录
A-圆周率日挑战
思路:上py吧,感觉这是py最有用的一集
import decimal
pi = decimal.Decimal("3.1415926535897932384626433832795028841971")
ans, res, d = 0, 0, 4
for i in range(int(input())):
p, a = map(int, input().split())
var = abs(decimal.Decimal(decimal.Decimal(p) / decimal.Decimal(a)) - pi)
if var == d:
if p < ans:
ans, res = p, a
elif var < d:
d = var
ans, res = p, a
print(ans, res)
B-正则表达式
思路:按题意模拟即可
void solve()
{
int n;
std::cin>>n;
i64 res=0;
while (n--)
{
bool f=0;
std::string s;
std::cin>>s;
int tmp=0;
for(auto &x:s)
{
if(x=='.')
{
if(tmp<0||tmp>255) f=1;
tmp=0;
continue;
}
tmp=tmp*10+x-'0';
}
if(tmp<0||tmp>255) f=1;
if(!f) res++;
}
std::cout<<res<<'\n';
}
C-Circle
思路:找规律
void solve()
{
int n;
std::cin>>n;
for(int i=0;i<n;i++)
{
int x;
std::cin>>x;
std::cout<<(x==0?1:(i64)x*x-x+2)<<" \n"[i==n-1];
}
}
D-开心消消乐(Right Version)
思路:O(n)扫一遍即可
void solve()
{
int n;
std::cin>>n;
int cmp=-1,res=0;
for(int i=0;i<n;i++)
{
int x;
std::cin>>x;
if(x!=cmp)
{
cmp=x;
if(x) res++;
}
}
std::cout<<res<<'\n';
}
F-累加器
思路:观察二进制位的变化,算一下0~x和0~x+y的次数作差即可
void solve()
{
int x,y;
std::cin>>x>>y;
int c=x+y;
i64 res1=0,res2=0;
while (x)
{
res1+=x/2;
x/=2;
}
while (c)
{
res2+=c/2;
c/=2;
}
std::cout<<res2-res1+y<<'\n';
}
G-求值
思路:枚举x,三分y,每次更新最小值
void solve()
{
i64 a,b,c,n,w;
std::cin>>a>>b>>c>>n>>w;
auto check=[&](i64 mid,i64 x)->i64
{
return std::abs(a*x+b*mid+(n-mid-x)*c-w);
};
i64 res=1e18;
for(int i=0;i<=n;i++)
{
i64 l=0,r=n-i;
while (l<=r)
{
i64 m1=l+(r-l)/3;
i64 m2=r-(r-l)/3;
res=std::min({res,check(m1,i),check(m2,i)});
if(check(m1,i)>check(m2,i))
l=m1+1;
else
r=m2-1;
}
}
std::cout<<res<<'\n';
}
I-游戏
思路:
结果为两种情况:
1.不使用钥匙到n的花费
2.到k之前无法使用钥匙的花费,之后使用钥匙解锁无法通过的道路到n的花费
跑两次最短路即可
void solve()
{
int n,m,k;
std::cin>>n>>m>>k;
k--;
std::vector<std::vector<std::array<i64,3>>>adj(n);
for(int i=0;i<m;i++)
{
i64 u,v,w,d;
std::cin>>u>>v>>w>>d;
u--,v--;
adj[u].pb({v,w,d});
adj[v].pb({u,w,d});
}
std::priority_queue<std::pair<i64,i64>,std::vector<std::pair<i64,i64>>,std::greater<>> q;
std::vector<i64> dis(n,1e18);
std::vector<bool> vis(n,0);
dis[0]=0;
q.push({0,0});
while(sz(q))
{
auto [x,y]=q.top();
q.pop();
int u=y;
if(vis[u]) continue;
vis[u]=1;
for(auto [v,w,d]:adj[u])
{
if(d)
{
dis[v]=std::min(dis[v],dis[u]+w);
q.push({dis[v],v});
}
}
}
i64 res=dis[n-1],tmp=dis[k];
std::fill(dis.begin(), dis.end(),1e18);
std::fill(vis.begin(), vis.end(),0);
dis[k]=0;
q.push({0,k});
while(sz(q))
{
auto [x,y]=q.top();
q.pop();
int u=y;
if(vis[u]) continue;
vis[u]=1;
for(auto [v,w,d]:adj[u])
{
dis[v]=std::min(dis[v],dis[u]+w);
q.push({dis[v],v});
}
}
res=std::min(res,tmp+dis[n-1]);
std::cout<<(res==1e18?-1:res)<<'\n';
}
J-keillempkill学姐の卷积
思路:按题意模拟即可
void solve()
{
int n,m;
std::cin>>n>>m;
std::vector<std::vector<int>>a(n,std::vector<int>(n,0)),b(m,std::vector<int>(m,0));
for(auto &y:a)
for(auto &x:y)
std::cin>>x;
for(auto &y:b)
for(auto &x:y)
std::cin>>x;
for(int i=0;i+n<=m;i++)
{
for(int j=0;j+n<=m;j++)
{
int res=0;
for(int di=0;di<n;di++)
for(int dj=0;dj<n;dj++)
res+=b[i+di][j+dj]*a[di][dj];
std::cout<<res<<" \n"[j==m-n];
}
}
}
K-暴食之史莱姆
思路:贪心的LIS,一个史莱姆能吃掉的最大个数应该为两侧小于它体积的第一个的史莱姆能吃掉的个数 + 1,先固定左侧,用单调栈维护一下该侧比当前史莱姆更小的第一个位置,右侧同理
void solve()
{
int n;
std::cin>>n;
std::vector<int>a(n+1,0);
for(int i=1;i<=n;i++) std::cin>>a[i];
std::vector<int>f1(n+1,0),f2(n+1,0);
std::stack<int>st;
for(int i=1;i<=n;i++)
{
while (sz(st)&&a[st.top()]>a[i]) st.pop();
if(sz(st)) f1[i]=f1[st.top()]+1;
st.push(i);
}
while (sz(st)) st.pop();
for(int i=n;i;i--)
{
while (sz(st)&&a[st.top()]>a[i]) st.pop();
if(sz(st)) f2[i]=f2[st.top()]+1;
st.push(i);
}
for(int i=1;i<=n;i++) std::cout<<f1[i]+f2[i]<<" \n"[i==n];
}
L-SSH
思路:读题读半天又挺ex的字符串模拟
void solve()
{
int n,m,q;
std::cin>>n>>m>>q;
std::map<std::string,std::string>mp;
for(int i=0;i<n;i++)
{
std::string pub,pri;
std::cin>>pub>>pri;
mp[pri]=pub;
}
std::map<std::string,std::map<std::string,std::set<std::string>>>mpp;
for(int i=0;i<m;i++)
{
std::string ip;
int k;
std::cin>>ip>>k;
for(int j=0;j<k;j++)
{
std::string user;
int t;
std::cin>>user>>t;
for(int p=0;p<t;p++)
{
std::string pub;
std::cin>>pub;
mpp[ip][user].insert(pub);
}
}
}
for(int i=0;i<q;i++)
{
std::string name,ip,pri;
std::cin>>name>>ip>>pri;
if(mpp[ip][name].count(mp[pri])) std::cout<<"Yes\n";
else std::cout<<"No\n";
}
}