A. Patrick and Shopping
【题意】 Patrick 从家出发去超市,超市A离家d1,超市B离家d2,超市A,B相距d3, Patrick 要去两个超市并返回家。求最短距离。
【分析】一共四种情况,算出最小值
【代码】
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<cstdio> using namespace std; const int maxn=0x3fffffff; int main (void) { int d1,d2,d3,t[4]; scanf("%d%d%d",&d1,&d2,&d3); t[0]=d1+d2+d3; t[1]=2*d1+2*d3; t[2]=2*d1+2*d2; t[3]=2*d2+2*d3; sort(t,t+4); printf("%d ",t[0]); }
B. Spongebob and Joke
【题意】给定长度为n的数组f和长度为m的数组b,问能否找到长度为m的数组a使得b[i]=f[a[i]],若数组a不存在,输出impossible,若不唯一,输出Ambiguity,若唯一,输出impossible及数组a。
【分析】注意先判断是否是impossible再判断Ambiguity
【代码】
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<cstdio> using namespace std; const int maxn=100050; int b[maxn]; int a[maxn]; int cnt[maxn]; int sf[maxn]; int main (void) { int m,n,temp, flag1=0,flag2=0; scanf("%d%d",&n,&m); fill(cnt,cnt+maxn,0); for(int i=0;i<n;i++) { scanf("%d",&temp); cnt[temp]++; sf[temp]=i+1; } for(int i=0;i<m;i++) scanf("%d",&b[i]); for(int i=0;i<m;i++) { if(cnt[b[i]]==0)flag1=1; if(cnt[b[i]]>1) flag2=2; a[i]=sf[b[i]]; } if(flag1==1) printf("Impossible "); else if(flag2==2) printf("Ambiguity "); else { printf("Possible "); printf("%d",a[0]); for(int i=1;i<m;i++) printf(" %d",a[i]); } return 0; }C. Day at the Beach
【题意】给定一系列数,对他们进行分块排序,使得最终整个数组为有序的,问最多可以分多少块。
【分析】可以直接判断该数前面的最大值是否小于后面的最小值,如果满足则可以将他单独划为一个block,否则将并到前面的block中。
Let’s take a minute to see how the best answer should look like. Let Hi be a sorted sequence of hi. Let E — set of indices of the last elements of each block. Then e E, first e sorted elements of sequence hi are equal to the first e elements of the sequence Hj. So, it is not difficult to notice that the size of E is the answer for the problem. Firstly, we need to calculate two arrays: prefmax and suffmin, where prefmaxi — maximum between a1, a2, …, ai, and suffmini — minimum between ai, ai + 1, …, an. If you want to get the answer, just calculate the number of indices i that prefmaxi ≤ suffmini + 1. Time: O(N)
【代码】
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<cstdio> #include<vector> using namespace std; const int maxn=100050; const int INF=0x3fffffff; int h[maxn],suffMax[maxn],suffMin[maxn]; int main (void) { int num,total=0; scanf("%d",&num); for(int i=1;i<=num;i++) scanf("%d",&h[i]); suffMin[num+1]=INF; suffMax[0]=-INF; for(int i=1;i<=num;i++) suffMax[i]=max(suffMax[i-1],h[i]); for(int i=num;i>=1;i--) suffMin[i]=min(suffMin[i+1],h[i]); for(int i=1;i<=num;i++) { if(suffMin[i+1]>=suffMax[i]) total++; } printf("%d",total); return 0; }
D. Spongebob
and Squares
【分析】不难得出公式。悲哀的是明明公式已经找到可是写了半天就是wa。注意上限!!!!
设n<=m,则对于i在[1,n],对(n-i+1)*(m-i+1)求和,化简之后为m*n*(n+1)/2-(n*n*n-n)/6
【代码】
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<cstdio> #include<vector> using namespace std; const int maxn=1000000LL; const int INF=0x3fffffff; typedef long long ll; vector<pair<ll,ll> > v; int main (void) { ll num; scanf("%I64d",&num); for(ll n=1;2*n*n*n+3*n*n+n<=7*num||n<=maxn;n++) { ll x1 = (n+1)*n/2ll; ll x2= (n*n*n-n)/6ll; ll temp=num+x2; if(temp%x1==0) { ll m=temp/x1; if(n>m) continue; v.push_back(make_pair(m,n)); if(n!=m) v.push_back(make_pair(n,m)); } } sort(v.begin(),v.end()); printf("%d ",v.size()); for(int i=0;i<v.size();i++) printf("%I64d %I64d ",v[i].first,v[i].second); return 0; }