2017 Multi-University Training Contest - Team 6—HDU6098&&HDU6106&&HDU6103
HDU6098 Inversion
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6098
题目意思:题目很短,给出一个数组,下标从1开始,现在输出一个数组,下标为j的数为表示原来的数组中下标j%i(当前数组中的下标)!=0中最大的数。
思路:很简单,将原来的一个数组的值带下标组成一个结构体,按照值得大小从大到小排序,然后对于每次询问从头扫第一个符合j%i!=0的值就是答案。
代码:
1 //Author: xiaowuga 2 #include <iostream> 3 #include <algorithm> 4 #include <set> 5 #include <vector> 6 #include <queue> 7 #include <cmath> 8 #include <cstring> 9 #include <cstdio> 10 #include <ctime> 11 #include <map> 12 #include <bitset> 13 #include <cctype> 14 #define maxx INT_MAX 15 #define minn INT_MIN 16 #define inf 0x3f3f3f3f 17 #define mem(s,ch) memset(s,ch,sizeof(s)) 18 #define nc cout<<"nc"<<endl 19 #define sp " " 20 const long long N=100000+10; 21 using namespace std; 22 typedef long long LL; 23 typedef int II; 24 struct node{ 25 LL val,pos; 26 bool operator <(const node& m) const{ 27 return val>m.val; 28 } 29 }a[N]; 30 II n; 31 int main() { 32 ios::sync_with_stdio(false);cin.tie(0); 33 II T; 34 cin>>T; 35 while(T--){ 36 cin>>n; 37 for(II i=1;i<=n;i++){ 38 cin>>a[i].val; 39 a[i].pos=i; 40 } 41 sort(a+1,a+n+1); 42 II flag=1; 43 for(II i=2;i<=n;i++){ 44 for(II j=1;j<=n;j++){ 45 if(a[j].pos%i!=0){ 46 if(flag) {cout<<a[j].val;flag=0;} 47 else cout<<sp<<a[j].val; 48 break; 49 } 50 } 51 } 52 cout<<endl; 53 } 54 return 0; 55 }
HDU6106 Classes
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6106
题目意思:有n个班级,给出一个班选a课程,选b课程,选c课程的,选ab课程的,选ac课程的,选bc课程的人数。有的班数据可能有错(比如给出的数据导致选某个课的人数为负数),我们直接忽略。找出班级人数最大的班级,并输出人数。
思路:这里说明一下带有o前缀代表只选了选某个课程的人数,我们可以画一个ven图。发现存在以下关系
oab=ab-abc; oa=a-ab-ac+abc;
oac=ac-abc; ob=b-ab-bc+abc;
obc=bc-abc; oc=c-ac-bc+abc;
以上所有的算出来否不能为负数才是合法的数据,否则忽略直接计算下一组数据。
如果是合法,oa+ob+oc+oab+obc+oac+abc就是这个班的人数,在数据是合法的班里面找出人数最多的班输出他们的人数。
代码:
1 //Author: xiaowuga 2 #include <iostream> 3 #include <algorithm> 4 #include <set> 5 #include <vector> 6 #include <queue> 7 #include <cmath> 8 #include <cstring> 9 #include <cstdio> 10 #include <ctime> 11 #include <map> 12 #include <bitset> 13 #include <cctype> 14 #define maxx INT_MAX 15 #define minn INT_MIN 16 #define inf 0x3f3f3f3f 17 #define mem(s,ch) memset(s,ch,sizeof(s)) 18 #define nc cout<<"nc"<<endl 19 #define sp " " 20 const long long N=100000; 21 using namespace std; 22 typedef long long LL; 23 typedef int II; 24 II n,a,b,c,ab,ac,bc,abc; 25 int main() { 26 ios::sync_with_stdio(false);cin.tie(0); 27 II T; 28 cin>>T; 29 while(T--){ 30 II ans=0; 31 cin>>n; 32 for(II i=0;i<n;i++){ 33 cin>>a>>b>>c>>ab>>bc>>ac>>abc; 34 II oab=ab-abc; 35 II oac=ac-abc; 36 II obc=bc-abc; 37 if(oab<0||obc<0||oac<0) continue; 38 II oa=a-ab-ac+abc; 39 II ob=b-ab-bc+abc; 40 II oc=c-ac-bc+abc; 41 if(oa<0||ob<0||oc<0) continue; 42 ans=max(ans,oa+ob+oc+oab+obc+oac+abc); 43 } 44 cout<<ans<<endl; 45 } 46 return 0; 47 }
HDU6103 Kirinriki
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6103
题目意思:在一个字符串S里面找出两个不重叠且长度相等的长度为n的子串,使得两个子串的dist不大于m,问n的最大值是多少?
思路:比赛的时候智障,没想到枚举中心,尽然没有写出来,这里说下为什么枚举中心。因为作为答案两个字符串一定关于某一个中心对称。我们以某个中心,从两边两个指针,往里面缩进,从而找到dist最近m的边界值。然后头尾指针缩进一格,减去头尾指针的贡献。然后继续直到下一次接近m的边界值。过程中记录长度的最大值。这里注意奇数中心和偶数中心的问题,我因此wa了一发。orz
代码:
1 //Author: xiaowuga 2 #include <iostream> 3 #include <algorithm> 4 #include <set> 5 #include <vector> 6 #include <queue> 7 #include <cmath> 8 #include <cstring> 9 #include <cstdio> 10 #include <ctime> 11 #include <map> 12 #include <bitset> 13 #include <cctype> 14 #define maxx INT_MAX 15 #define minn INT_MIN 16 #define inf 0x3f3f3f3f 17 #define mem(s,ch) memset(s,ch,sizeof(s)) 18 #define nc cout<<"nc"<<endl 19 #define sp " " 20 const long long N=5005; 21 using namespace std; 22 typedef long long LL; 23 typedef int II; 24 char q[N]; 25 int main() { 26 II T; 27 scanf("%d",&T); 28 II ct,sum; 29 while(T--){ 30 II m; 31 scanf("%d",&m); 32 getchar(); 33 scanf("%s",q); 34 II ans=0,ct,sum; 35 II len=strlen(q); 36 for(II i=0;i<len-1;i++){ 37 II lim=min(i+1,len-i-1); 38 II l=i-lim+1,r=i+lim; 39 II x=l,y=r; 40 sum=ct=0; 41 for(II k=0;k<lim;){ 42 II t=abs(q[x+k]-q[y-k]); 43 if(sum+t<=m){ 44 sum+=t; 45 ct++; 46 ans=max(ans,ct); 47 k++; 48 } 49 else{ 50 sum-=abs(q[l]-q[r]); 51 l++;r--; 52 ct--; 53 } 54 } 55 lim=min(i,len-i-1); 56 x=l=i-lim;y=r=i+lim; 57 sum=ct=0; 58 for(II k=0;k<lim;){ 59 II t=abs(q[x+k]-q[y-k]); 60 if(sum+t<=m){ 61 sum+=t; 62 ct++; 63 ans=max(ans,ct); 64 k++; 65 } 66 else{ 67 sum-=abs(q[l]-q[r]); 68 l++;r--; 69 ct--; 70 } 71 } 72 } 73 cout<<ans<<endl; 74 } 75 return 0; 76 }