A:https://codeforces.com/contest/1358/problem/A
题意:
n*m格子,灯只能放在每条街中间位置,求最少的灯来点亮所有的格子。
解析:
做这种题有点小阴影。生怕错过哪个情况,所以总是写的很繁琐。
分类讨论即可
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=60; int mp[maxn][maxn]; int main() { int t; cin>>t; while(t--) { int n,m; cin>>n>>m; int md; if(n%2==0&&m%2==0) cout<<n*m/2<<endl; else if(n%2!=0&&m%2==0) cout<<n*m/2<<endl; else if(n%2==0&&m%2!=0) cout<<n*m/2<<endl; else { int sum=(n-1)*(m-1)/2; cout<<sum+max((n-1)/2+m/2+1,(m-1)/2+n/2+1)<<endl; } } }
B:https://codeforces.com/contest/1358/problem/B
题意:
每个人有一个ai,要想让他进场,那么除了他以外,当前场里人数要>=ai。记得主角也要算一个人。
解析:
排序后从后往前遍历,找到第一个ai<=i+1的即可,
这样的话,此ai之前的所有人一块进场,一定是满足条件的。
找不到就说明只能主角本人一个人在场,输出1。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=1e5+10; int a[maxn]; int main() { int t; cin>>t; while(t--) { int n; cin>>n; for(int i=0;i<n;i++) cin>>a[i]; sort(a,a+n); int ok=0,k; int sum=0; for(int i=n-1;i>=0;i--) { if(a[i]<=i+1) { // cout<<a[i]<<endl; ok=1; sum=sum+i+2; break; } } if(!ok) cout<<"1"<<endl; else cout<<sum<<endl; } }
C:https://codeforces.com/contest/1358/problem/C
题意:按题中所给的图,给出x1,y1,x2,y2,求从(x1,y1)到(x2,y2)的sum种类数。只能向下方和右方移动。
解析:
比赛时盲猜的结论,现在我好好分析一遍,供大家参考。
很容易可以看出,⬇到底,然后→,为最大sum。 →到底,然后⬇,为最小sum
那么min<=x<=max,中间所有的数都会被加到,就是种类数。所以只要求出max-min+1就好了。
我们只看上面提到的两个路线。
设n*m,n为较短的一边
每次求两个位置的差值,可以得出差值来:
1+2+.....+n-1...+n-1+.....+n-1+......+1
n-1的个数是未知的,由于上面是一条完整路线,根据总步数:n+m-3,可以求出n-1的数目来:
n+m-3-2*(n-1)==m-n-1个n-1(已去掉两边的n-1)
两个1~n-1就是等差数列和:n*n-n
总的差值就为:n*n-n+(m-n-1)*(n-1)
化简为:m*n-m-n+1。
对于[L,R]中间一共为R-L+1个数
所以为m*n-m-n+2==(n-1)*(m-1)+1==(x2-x1)*(y2-y1)+1
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const int maxn=1e5+10; int a[maxn]; int main() { int t; cin>>t; while(t--) { ll x1,y1,x2,y2; cin>>x1>>y1>>x2>>y2; cout<<(x2-x1)*(y2-y1)+1<<endl; } }