官方解题报告
1001 hdu 4350Card
题意:
给定52张牌,按顺序排列着,给出操作每次讲下表为[l,r]的牌一道最前边,问执行n次这样的操作后最终序列的情况。
思路:
给定的n比较大,直接模拟肯定tle,首先我们发现移动m次[l,r]后肯定会出现循环的情况,所以我们只要找出循环节,然后n %= m 然后剩下的模拟就可以;
View Code
#include#include #include #include #include #define maxn 66using namespace std;int a[maxn],b[maxn];int gcd(int a,int b){ if (b == 0) return a; else return gcd(b,a%b);}int main(){ //freopen("d.txt","r",stdin); int L,R,i,j; int t,n; int cas = 1; scanf("%d",&t); while (t--) { for (i = 1; i <= 52; ++i) scanf("%d",&a[i]); //for (i = 1; i <= 52; ++i) printf("%d ",a[i]); scanf("%d%d%d",&n,&L,&R); int d = ((R - L + 1)*R)/gcd(R - L + 1,R);//找出循环节 n %= d; while (n--)//模拟 { j = 1; int len = R - L + 1; for (i = L; i <= R; ++i) b[j++] = a[i]; for (i = L - 1; i >= 1; --i) a[i + len] = a[i]; for (i = 1; i < j; ++i) a[i] = b[i]; } printf("Case #%d:",cas++); for (i = 1; i <= 52; ++i) printf(" %d",a[i]); printf("\n"); } return 0;}
1006 hdu 4355 Party All the Time
题意:
在x坐标轴上给出n个点的x坐标以及他们本身的权值w,求能够找出一点Xm是的所有点到该店的距离Si Si^3*wi的和最小。
思路:
才开始我以为找到中点,前后枚举100个点蹭一下数据可以过,可是一看这里x坐标是小数啊,你怎么枚举,只好错误的做了一下结果真的wa.这题写出公式函数是一个凹函数,直接套三分模板即可。
View Code
#include#include #include #include #include #include #define maxn 50007using namespace std;const double inf = 0x7fffffff;const double eps = 1e-4;struct node{ double x,w;}p[maxn];int n;int dbcmp(double x){ if (x > eps) return 1; else if (x < -eps) return -1; else return 0;}double getS(int x,double y){ return fabs((p[x].x - y)*(p[x].x - y)*(p[x].x - y))*p[x].w;}double getR(double x){ double sum = 0; for (int i = 0; i < n; ++i) { sum += getS(i,x); } return sum;}void solve(double l,double r,int cas){ double m,mm; while (dbcmp(r - l) > 0) { m = (l + r)/2.0; mm = (m + r)/2.0; if (getR(m) >= getR(mm)) l = m; else r = mm; } printf("Case #%d: %.0lf\n",cas,getR(l));}int main(){ //freopen("d.txt","r",stdin); int t,i; int cas = 1; scanf("%d",&t); while (t--) { scanf("%d",&n); double l = inf; double r = -inf; for (i = 0; i < n; ++i) { scanf("%lf%lf",&p[i].x,&p[i].w); l = min(l,p[i].x); r = max(r,p[i].x); } solve(l,r,cas); cas++; } return 0;}
1008 hdu4357String change
题意:
给你两个字符串,s1,s2,问是都能够通过交换s1里面的任意两个字符串并且同时字符串要+1,得到s2;
思路:
官方解题报告有证明不在多说,给代码,MB在最后的几分钟写的,结果把两数交换给写错了,导致最后没有AC。。悲剧啊。。
View Code
#include#include #include #include #include #define maxn 66using namespace std;char s1[maxn],s2[maxn];int main(){ //freopen("d.txt","r",stdin); int t; int i; int cas = 1 ; scanf("%d",&t); while (t--) { scanf("%s%s",s1,s2); int len = strlen(s1); if (len == 2) { int a1 = s1[0] - 'a' + 1; int b1 = s1[1] - 'a' + 1; int a2 = s2[0] - 'a' + 1; int b2 = s2[1] - 'a' + 1; i = 1; while (i <= 26) { if (a1 == a2 && b1 == b2) break; a1++; b1++; if (a1 > 26) a1 %= 26; if (b1 > 26) b1 %= 26; int tmp = a1; a1 = b1; b1 = tmp; i++; } if (a1 == a2 && b1 == b2) printf("Case #%d: YES\n",cas++); else printf("Case #%d: NO\n",cas++); } else { int sum1 = 0,sum2 = 0; for (i = 0; i < len; ++i) { sum1 += s1[i] - 'a' + 1; sum2 += s2[i] - 'a' + 1; } if ((sum1%2 == 0 && sum2%2 == 0) || (sum1%2 == 1 && sum2%2 == 1)) { printf("Case #%d: YES\n",cas++); } else { printf("Case #%d: NO\n",cas++); } } } return 0;}