題意:
有三個三面骰,會給你他骰一萬次後,出現各面的次數
然後再給你一個三面出現的次數,問說能不能用這三個骰子擲出這次數
解法:
可以把三面骰的三個值當作x , y, z ,然後因為x+y+z都是10000,所以可以直接改成x+y = 10000-z
投影到xy平面不看z;轉換之後,題目就變成:
給三個平面座標點,問一點有沒有在三點中間(不行在點上或是線上,因為三顆骰子都要用到
一般的測資可以用外積去判斷
特殊測資(三點共線)就要看,要看 要求的次數x是否大於最小x以及小於最大x,或是 要求的次數y是否大於最小y以及小於最大y(介於最大與最小間才行由三個組成)
程式碼:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int dice[4][3];
int cross(int o,int a,int b){
int x1 = dice[a][0]-dice[o][0];
int x2 = dice[b][0]-dice[o][0];
int y1 = dice[a][1]-dice[o][1];
int y2 = dice[b][1]-dice[o][1];
if(x1*y2-x2*y1>0)return 1;
if(x1*y2-x2*y1<0)return -1;
return 0;
}
int main(){
int i,j;
while(scanf("%d %d %d",&dice[0][0],&dice[0][1],&dice[0][2])){
if(dice[0][0]+dice[0][1]+dice[0][2]<10000)break;
for(i=1;i<4;++i)scanf("%d %d %d",&dice[i][0],&dice[i][1],&dice[i][2]);
if(cross(0,1,2)==0){
if(dice[0][0]==dice[1][0] && dice[1][0]==dice[2][0]){
for(i=0;i<3 &&dice[3][1]>=dice[i][1];++i);
for(j=0;j<3 &&dice[3][1]<=dice[j][1];++j);
}else {
for(i=0;i<3 &&dice[3][0]>=dice[i][0];++i);
for(j=0;j<3 &&dice[3][0]<=dice[j][0];++j);
}
if(cross(0,1,3)!=0 || i>=3 ||j>=3) puts("NO");
else puts("YES");
}else {
for(i=0;i<3 && cross(3,i,(i+1)%3)*cross(3,(i+1)%3,(i+2)%3)>0;++i);
if(i>=3)puts("YES");
else puts("NO");
}
}
return 0;
}
留言列表