昨天打了场小白月赛,前3题出题极慢,还wa了一发,最终过了三题,排名470/1500,rating加了5分,差点扣分....现rating1231,继续加油啊;
md,A题看题意看了好久,一直在想第n个平台是哪一个平台还是全部的平台啊,其实第n的平台中的n就是我们输入的,我真是傻子....
我们只需要考虑第一个平台和第n个平台的高度即可
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
using namespace std;
typedef long long ll ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
void print(__int128 num) {
if(num) {
print(num/10);
putchar(num%10+'0');
}
}
int n;
int a[100005];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
if(a[1]>=a[n]){
printf("NO\n");
}else{
printf("YES\n");
}
return 0;
}
这题我一下下去就有了思路了,因子的个数为奇数的数一定是完全平方数,即(int)sqrt(i)*(int)sqrt(i)=i;然后我就想了想,有没有i不是完全平方数,但(int)sqrt(i)*(int)sqrt(i)=i的数呢;
想了想应该是没有的..
然后就交了,就ac了
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
using namespace std;
typedef long long ll ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
void print(__int128 num) {
if(num) {
print(num/10);
putchar(num%10+'0');
}
}
int t;
int main(){
int n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
int cnt=0;
for(double i=1;i<=n;i++){
int m=sqrt(i);
if(m*m==i)cnt++;
}
printf("%d\n",cnt);
}
return 0;
}
这题其实并不难,其实abc都不难,md我一直知不道样例是怎么出来的,所以读题读了好久,一开始我以为1≤i<j≤n,但是题目是1≤i,j≤n,i和j只要不相等即可,我真的是傻x...
然后看代码即可
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
using namespace std;
typedef long long ll ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
void print(__int128 num) {
if(num) {
print(num/10);
putchar(num%10+'0');
}
}
int n;
int a[100005];
int b[100005];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
}
ll ans1=0;
ll ans2=0;
for(int i=1;i<=n;i++){
if(a[i]-b[i]<=0){
ans1=ans1+abs(a[i]-b[i]);
}else{
ans2=ans2+a[i]-b[i];
}
}
if(ans1==ans2){
printf("%lld\n",ans1);
}else{
printf("-1\n");
}
return 0;
}
这题开始的时候我一直思考用搜索好呢还是用dp呢...看到n和m的范围我感觉搜索一定会超时,所以我感觉用dp,一开始我是把传送门排序的,但是想了一会,发现排序不一定是最优的,比如(x1,y1)和(x2,y2),因为宝藏有正有负,而且如果宝藏是正的,也不一定满足我们的理想条件,即x1<=x2&&y1<=y2。但是传送门的个数很小,所以可以枚举
我们需要统计的是(1,1)->(n,m)和(1,1)->(x1,y1)->(x2,y2)->(n,m)的最值
我比赛的时候写的是(1,1)->(n,m)和(1,1)->(n,m)+(x1,y1)->(x2,y2)的最值
我们用dp[i][j]来存储(1,1)到(x1,y1)的最值
用dp1[i][j]来存储(x2,y2)到(n,m)的最值
dp1[n][m]=a[n][m];
for(int i=n;i>=1;i--){
for(int j=m;j>=1;j--){
if(i==n&&j==m)continue;
dp1[i][j]=max(dp1[i+1][j],dp1[i][j+1])+a[i][j];
}
}
dp1是倒着循环的,如果正着循环的话,dp1对于每一个(x2,y2)都需要循环一次;
倒着循环的话,我们只需要循环一次即可;‘
注意ans要赋值为dp[n][m],因为我们还可以不采用传送门的情况
#include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<string.h> #include<queue> #include<stack> #include<deque> #include<vector> #include<map> #include<set> #include <utility> using namespace std; typedef long long ll ; #define pii pair<int,int> const int inf = 0x3f3f3f3f;//106110956 inline int read(){ int x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if (ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ x = (x<<1) + (x<<3) + (ch^48); ch = getchar(); } return x * f; } void print(__int128 num) { if(num) { print(num/10); putchar(num%10+'0'); } } int n,m; ll dp[1005][1005]; ll dp1[1005][1005]; int a[1005][1005]; struct Node{ int x,y; }b[10]; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&a[i][j]); } } int t; scanf("%d",&t); memset(dp,-inf,sizeof(dp)); memset(dp1,-inf,sizeof(dp1)); dp[1][1]=a[1][1]; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(i==1&&j==1)continue; dp[i][j]=max(dp[i-1][j],dp[i][j-1])+a[i][j]; } } dp1[n][m]=a[n][m]; for(int i=n;i>=1;i--){ for(int j=m;j>=1;j--){ if(i==n&&j==m)continue; dp1[i][j]=max(dp1[i+1][j],dp1[i][j+1])+a[i][j]; } } while(t--){ int k; scanf("%d",&k); for(int i=1;i<=k;i++){ scanf("%d%d",&b[i].x,&b[i].y); } ll ans=dp[n][m];//不要忘记可以不用传送门的情况 for(int i=1;i<=k;i++){//传送的地方 for(int j=1;j<=k;j++){//传到的地方 if(i==j)continue; ans=max(ans,dp[b[i].x][b[i].y]+dp1[b[j].x][b[j].y]); } } printf("%lld\n",ans); } return 0; }
这题比赛的时候没有做,赛后补的,如果做的话,也做不出来啊
我的思路:暴力双层循环,铁定会超时,二分也没想出来怎么做..
正确:二分答案+双指针思想
将a和b从小到大排序,然后如图,枚举i,然后如果while(a[i]*b[r]>mid&&r)r--;
cnt=cnt+r;
对于二分,因为注意等于要在right=mid-1的情况写,因为mid可能不存在,如果不存在的话,right=mid-1;
对于不能在一起的食物和烹饪方法,我们提前把他们入vector,然后如果vector里的数小于mid,
cnt--即可;
ll check(ll mid){
int r=m;
ll cnt=0;
for(int i=1;i<=n;i++){
while(a[i]*b[r]>mid&&r)r--;
cnt=cnt+r;
}
for(int i=0;i<k;i++){
if(s[i]<=mid){
cnt--;
}
}
return cnt;
}
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
using namespace std;
typedef long long ll ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
void print(__int128 num) {
if(num) {
print(num/10);
putchar(num%10+'0');
}
}
int n,m,k,q;
int a[1000006];
int b[1000006];
vector<ll>s;
ll check(ll mid){
int r=m;
ll cnt=0;
for(int i=1;i<=n;i++){
while(a[i]*b[r]>mid&&r)r--;
cnt=cnt+r;
}
for(int i=0;i<k;i++){
if(s[i]<=mid){
cnt--;
}
}
return cnt;
}
int main(){
scanf("%d%d%d%d",&n,&m,&k,&q);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=m;i++){
scanf("%d",&b[i]);
}
int x,y;
for(int i=1;i<=k;i++){
scanf("%d%d",&x,&y);
s.push_back(a[x]*b[y]);
}
sort(a+1,a+1+n);
sort(b+1,b+1+m);
while(q--){
int x;
scanf("%d",&x);
ll right=1e15;
ll left=0;
while(left<=right){
ll mid=(left+right)/2;
if(check(mid)>=x){
right=mid-1;
}else{
left=mid+1;
}
}
printf("%lld\n",right+1);
}
return 0;
}