<cf> Prizes, Prizes, more Prizes

D. Prizes, Prizes, more Prizes
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Vasya, like many others, likes to participate in a variety of sweepstakes and lotteries. Now he collects wrappings from a famous chocolate bar "Jupiter". According to the sweepstake rules, each wrapping has an integer written on it — the number of points that the participant adds to his score as he buys the bar. After a participant earns a certain number of points, he can come to the prize distribution center and exchange the points for prizes. When somebody takes a prize, the prize's cost is simply subtracted from the number of his points.

Vasya didn't only bought the bars, he also kept a record of how many points each wrapping cost. Also, he remembers that he always stucks to the greedy strategy — as soon as he could take at least one prize, he went to the prize distribution centre and exchanged the points for prizes. Moreover, if he could choose between multiple prizes, he chose the most expensive one. If after an exchange Vasya had enough points left to get at least one more prize, then he continued to exchange points.

The sweepstake has the following prizes (the prizes are sorted by increasing of their cost):

  • a mug (costs a points),
  • a towel (costs b points),
  • a bag (costs c points),
  • a bicycle (costs d points),
  • a car (costs e points).

Now Vasya wants to recollect what prizes he has received. You know sequence p1, p2, ..., pn, where piis the number of points Vasya got for the i-th bar. The sequence of points is given in the chronological order. You also know numbers abcde. Your task is to find, how many prizes Vasya received, what prizes they are and how many points he's got left after all operations are completed.

Input

The first line contains a single integer n (1 ≤ n ≤ 50) — the number of chocolate bar wrappings that brought points to Vasya. The second line contains space-separated integers p1, p2, ..., pn (1 ≤ pi ≤ 109). The third line contains 5 integers abcde (1 ≤ a < b < c < d < e ≤ 109) — the prizes' costs.

Output

Print on the first line 5 integers, separated by a space — the number of mugs, towels, bags, bicycles and cars that Vasya has got, respectively. On the second line print a single integer — the number of points Vasya will have left after all operations of exchange are completed.

Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use thecincout streams or the %I64d specifier.

Sample test(s)
input
3
3 10 4
2 4 10 15 20
output
1 1 1 0 0 
1
input
4
10 4 39 2
3 5 10 11 12
output
3 0 1 0 3 
0
Note

In the first sample Vasya gets 3 points after eating the first chocolate bar. Then he exchanges 2 points and gets a mug. Vasya wins a bag after eating the second chocolate bar. Then he wins a towel after eating the third chocolate bar. After all chocolate bars 3 - 2 + 10 - 10 + 4 - 4 = 1 points remains.

#include <iostream>
#include <memory.h>
using namespace std;

int main()
{
    int n;
    long long cost[5],point[51],NumPri[5],LeftPoint;
    while(cin>>n)
    {
        LeftPoint=0;
        memset(NumPri,0,sizeof(NumPri));
        for(int i=0;i<n;i++)
            cin>>point[i];
        for(int i=0;i<5;i++)
            cin>>cost[i];
        for(int i=0;i<n;i++)
        {
            LeftPoint+=point[i];
            int j=1;
            while(j)
            {
                for(j=0;j<5 && LeftPoint>=cost[j];j++)
                {

                }
                if(j)
                {
                    //以下第一种做法会超时
                    //NumPri[j-1]++;
                    //LeftPoint-=cost[j-1];
                    NumPri[j-1]+=(LeftPoint/cost[j-1]);
                    LeftPoint-=(LeftPoint/cost[j-1]*cost[j-1]);
                }
            }
        }
        for(int i=0;i<4;i++)
           cout<<NumPri[i]<<" ";
        cout<<NumPri[4]<<endl<<LeftPoint<<endl;
    }
    return 0;
}


<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Poetry·Music·Gaming - Personal Webpage</title> <style> /* Global styles */ :root { --primary: #1a1a2e; --secondary: #0f3460; --accent: #e94560; --text: #f1f1f1; } * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Lato', sans-serif; background: linear-gradient(135deg, var(--primary), #16213e); color: var(--text); line-height: 1.6; padding: 20px; } .container { max-width: 1200px; margin: 0 auto; } section { background: rgba(10, 10, 20, 0.7); border-radius: 15px; padding: 30px; margin-bottom: 30px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); backdrop-filter: blur(10px); } h1, h2 { color: var(--accent); margin-bottom: 20px; text-shadow: 0 2px 4px rgba(0,0,0,0.5); } /* Poem section */ .poem { font-family: 'Playfair Display', serif; text-align: center; padding: 30px 0; } .poem-title { font-size: 2.5rem; margin-bottom: 10px; letter-spacing: 1px; } .poem-author { font-size: 1.2rem; opacity: 0.8; margin-bottom: 30px; font-style: italic; } .poem-content { font-size: 1.5rem; line-height: 2.2; letter-spacing: 0.5px; } .poem-line { margin: 15px 0; } /* MV player */ .player-container { position: relative; border-radius: 12px; overflow: hidden; margin: 30px 0; box-shadow: 0 10px 30px rgba(0,0,0,0.5); } .mv-frame { width: 100%; height: 500px; border: none; } /* Game intro section */ .game-info { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; margin-top: 30px; } .game-text { padding: 20px; } .game-features { display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; margin: 20px 0; } .feature-card { background: rgba(233, 69, 96, 0.15); padding: 15px; border-radius: 8px; border-left: 3px solid var(--accent); } .screenshot { border-radius: 10px; overflow: hidden; box-shadow: 0 5px 15px rgba(0,0,0,0.4); display: flex; align-items: center; } .screenshot img { width: 100%; height: auto; display: block; } /* Responsive design */ @media (max-width: 768px) { .game-info { grid-template-columns: 1fr; } .mv-frame { height: 300px; } .poem-content { font-size: 1.3rem; } } </style> <!-- Google Fonts --> <link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;700&family=Playfair+Display:wght@700&display=swap" rel="stylesheet"> </head> <body> <div class="container"> <!-- Header --> <header> <h1>Poetry · Music · Gaming</h1> <p>Where Classical Poetry Meets Modern Esports</p> </header> <!-- Poem Section --> <section id="poem"> <h2>"Ascending the Heights" - Du Fu (Tang Dynasty)</h2> <div class="poem"> <div class="poem-title">Ascending the Heights</div> <div class="poem-author">By Du Fu (712-770 AD)</div> <div class="poem-content"> <div class="poem-line">The wind so swift, the sky so wide, apes wail and cry;</div> <div class="poem-line">Water so clear and beach so white, birds wheel and fly.</div> <div class="poem-line">The boundless forest sheds its leaves shower by shower;</div> <div class="poem-line">The endless river rolls its waves hour after hour.</div> <div class="poem-line">A thousand miles from home, I'm grieved at autumn's plight;</div> <div class="poem-line">Ill now and then for years, alone I'm on this height.</div> <div class="poem-line">Living in times so hard, at frosted hair I pine;</div> <div class="poem-line">Cast down by poverty, I have to give up wine.</div> </div> </div> <p style="text-align: center; margin-top: 20px; font-style: italic;">Translated by Xu Yuanchong</p> </section> <!-- Music MV Section --> <section id="music"> <h2>"Ticking Away" - Valorant Champions 2023 Theme</h2> <div class="player-container"> <iframe width="560" height="315" src="https://www.youtube.com/embed/CdZN8PI3MqM?si=iaAwrEvd_YR1UxGH" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> </div> <div class="music-info"> <p><strong>Artist:</strong> Riot Games Music Team</p> <p><strong>Released:</strong> August 6, 2023</p> <p><strong>Event:</strong> Valorant Champions 2023 Grand Finals</p> <p><strong>Description:</strong> The official anthem for the 2023 Valorant Champions Tour, capturing the intensity and global spirit of the tournament.</p> </div> </section> <!-- Game Introduction Section --> <section id="game"> <h2>Valorant - Tactical Shooter Masterpiece</h2> <div class="game-info"> <div class="game-text"> <p>Valorant is a free-to-play tactical first-person shooter developed and published by Riot Games. Combining precise gunplay with unique character abilities, it has become a premier esports title since its 2020 release.</p> <div class="game-features"> <div class="feature-card"> <h3>Agent System</h3> <p>20+ unique Agents with special abilities</p> </div> <div class="feature-card"> <h3>Weapon Arsenal</h3> <p>17 weapons across 6 categories</p> </div> <div class="feature-card"> <h3>Competitive</h3> <p>Ranked mode with VCT global tournaments</p> </div> <div class="feature-card"> <h3>Map Design</h3> <p>7 tactically diverse maps</p> </div> </div> <h3>Core Gameplay</h3> <p>Matches are 25-round games where attackers try to plant a Spike while defenders attempt to stop them. The economy system forces strategic buying decisions each round. Valorant's 128-tick servers ensure precise hit registration where every millisecond counts[^1].</p> <h3>Esports Impact</h3> <p>Valorant Champions Tour (VCT) features international tournaments with millions in prizes. The 2023 Champions in Los Angeles set viewership records with over 1.4 million concurrent viewers[^2].</p> </div> <div class="screenshot"> <img src="https://images.contentstack.io/v3/assets/bltb6530b271fddd0b1/blt158572a7e9a2121e/62a0940b7fdb2a6d4f0dbb80/V_AGENTS_587x900_Brimstone.png" alt="Valorant Agent Brimstone"> </div> </div> </section> <!-- Footer --> <footer> <p>© 2023 Poetry · Music · Gaming | Fusion of Classical and Modern Culture</p> </footer> </div> </body> </html> 这是我的网页代码,现在我要让视频位置和尺寸合适,给出修改后的代码
06-15
<!DOCTYPE html> <html lang="zh-Hant"> <head> <meta charset="UTF-8" /> <title>3D 抽獎卡片展示</title> <style> body { margin: 0; height: 100vh; display: flex; justify-content: center; align-items: center; /* background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d); */ background-color: black; font-family: Arial, sans-serif; overflow: hidden; } .stage { perspective: 1200px; width: 400px; height: 500px; position: relative; } .card-stack { width: 100%; height: 100%; position: absolute; transform-style: preserve-3d; } .card { position: absolute; padding: 20px; width: 320px; left: 40px; top: 50%; transform: translateY(-50%); border-radius: 20px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.35); display: flex; flex-direction: column; backface-visibility: hidden; border: 3px solid black; overflow: hidden; transition: transform 0.8s, opacity 0.8s, z-index 0.8s; } .card-header { font-size: 32px; font-weight: bold; padding: 10px; text-align: center; border-bottom: 2px solid rgba(255, 255, 255, 0.5); } .card-body { padding: 10px; font-size: 18px; display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 5px; } .name { background: rgba(255, 255, 255, 0.25); padding: 3px 8px; border: 2px solid #fff; border-radius: 6px; font-size: 16px; font-weight: 500; } </style> </head> <body> <div class="stage"> <div class="card-stack" id="stack"> <div class="card"> <div class="card-header">頭獎 - iPhone</div> <div class="card-body"> <span class="name">小明</span><span class="name">小華</span ><span class="name">小美</span> </div> </div> <div class="card"> <div class="card-header">二獎 - iPad</div> <div class="card-body"> <span class="name">小強</span><span class="name">阿玲</span ><span class="name">阿杰</span><span class="name">小魚</span ><span class="name">小熊</span> </div> </div> <div class="card"> <div class="card-header">三獎 - AirPods</div> <div class="card-body"> <span class="name">小玉</span><span class="name">小芳</span> </div> </div> <div class="card"> <div class="card-header">四獎 - Starbucks</div> <div class="card-body"> <span class="name">阿文</span><span class="name">阿國</span ><span class="name">小紅</span><span class="name">小綠</span ><span class="name">小藍</span><span class="name">小紫</span ><span class="name">小白</span> </div> </div> <div class="card"> <div class="card-header">五獎 - 全聯禮券</div> <div class="card-body"> <span class="name">小美</span><span class="name">阿東</span> </div> </div> <div class="card"> <div class="card-header">六獎 - 小確幸</div> <div class="card-body"> <span class="name">阿良良</span><span class="name">小黑</span ><span class="name">小黃</span><span class="name">阿秋黑</span ><span class="name">小光</span><span class="name">阿星</span ><span class="name">小藍</span><span class="name">小草</span> <span class="name">阿良</span><span class="name">小黑</span ><span class="name">小黃</span><span class="name">阿秋</span ><span class="name">小光</span><span class="name">阿星</span ><span class="name">小藍</span><span class="name">小草</span> <span class="name">阿良</span><span class="name">小黑</span ><span class="name">小黃</span><span class="name">阿秋</span ><span class="name">小光</span><span class="name">阿星</span ><span class="name">小藍</span><span class="name">小草</span> </div> </div> </div> </div> <script> // 可選配色板 const textColorPalette = [ 0x3498db, 0xe74c3c, 0x2ecc71, 0xf1c40f, 0x9b59b6, 0x1abc9c, ]; const colorPalette = [ "#3498db", "#e74c3c", "#2ecc71", "#f1c40f", "#9b59b6", "#1abc9c", ]; const stack = document.getElementById("stack"); let cards = Array.from(stack.children); // 計算文字顏色對比度 function getTextColor(bgColor) { // Remove '#' and parse hex string to RGB const hex = bgColor.replace("#", ""); const r = parseInt(hex.substring(0, 2), 16); const g = parseInt(hex.substring(2, 4), 16); const b = parseInt(hex.substring(4, 6), 16); // Calculate brightness using the same formula const brightness = 0.299 * r + 0.587 * g + 0.114 * b; // Return hex color string based on brightness return brightness > 186 ? "#000000" : "#ffffff"; } // 套用顏色 cards.forEach((card, i) => { card.style.background = colorPalette[i % colorPalette.length]; // colors[i].bg; card.style.color = getTextColor(colorPalette[i % colorPalette.length]); // colors[i].text; }); function rotateCards() { let first = cards.shift(); cards.push(first); cards.forEach((card, i) => { if (i === 0) { card.style.transform = "translateY(calc(-50% - 180px)) translateZ(-250px) rotateX(55deg) scale(0.8)"; card.style.opacity = 0.5; card.style.zIndex = 1; } else if (i === 1) { card.style.transform = "translateY(-50%) translateZ(0px) rotateX(0deg) scale(1.2)"; card.style.opacity = 1; card.style.zIndex = 10; } else if (i === 2) { card.style.transform = "translateY(calc(-50% + 180px)) translateZ(-250px) rotateX(-55deg) scale(0.8)"; card.style.opacity = 0.5; card.style.zIndex = 1; } else { card.style.transform = "translateY(-50%) translateZ(-600px) scale(0.6)"; card.style.opacity = 0; card.style.zIndex = 0; } }); } rotateCards(); setInterval(rotateCards, 3000); </script> </body> </html> 將上述單一html檔案修改成. vite + vie3 + ts 其他功能一率不變,資料動態傳入,使用 props
09-04
<template> <view class="index-page"> <!-- 活动信息区域 --> <view v-if="currentActivity" class="activity-info"> <view class="activity-name">{{ currentActivity.name }}</view> <view class="activity-time"> {{ formatDate(currentActivity.startTime) }} - {{ formatDate(currentActivity.endTime) }} </view> <!-- 活动规则区域 --> <view class="activity-rules"> <text class="label">活动规则:</text> <text class="rules-text">{{ currentActivity.rules }}</text> <text class="view-rules" @click="goToRules">查看规则</text> </view> <view class="draw-count"> 今日剩余抽奖次数: {{ drawCount }}/{{ currentActivity.dailyLimit }} </view> </view> <!-- 抽奖转盘 --> <view class="wheel-container"> <lottery-wheel :prizes="prizes" ref="wheelRef" :spinning="drawing" /> </view> <!-- 抽奖按钮 --> <draw-button :disabled="drawing || drawCount >= maxDrawCount" @click="handleDraw" /> <!-- 奖品展示 --> <prize-show :prizes="prizes" /> <!-- 中奖记录预览 --> <view class="records-preview"> <view class="header"> <text>最新中奖记录</text> <text class="view-all" @click="goToRecords">查看全部</text> </view> <view v-for="(record, index) in recentRecords" :key="index" class="record-item"> <text class="user">{{ record.user }}</text> <text class="prize">{{ record.prize }}</text> <text class="time">{{ record.time }}</text> </view> </view> <!-- 中奖结果弹窗 --> <uni-popup ref="resultPopup" type="center"> <uni-popup-message v-if="resultPrize" :title="`恭喜获得${resultPrize.level}!`" :content="resultPrize.name" :duration="3000" @close="handlePopupClose" ></uni-popup-message> </uni-popup> </view> </template> <script> import { mapState, mapActions, mapMutations } from 'vuex' import LotteryWheel from './components/LotteryWheel.vue' import PrizeShow from './components/PrizeShow.vue' import DrawButton from '@/components/DrawButton.vue' import UniPopup from '@/components/uni-popup/uni-popup.vue' import UniPopupMessage from '@/components/uni-popup/uni-popup-message.vue' export default { components: { LotteryWheel, PrizeShow, DrawButton, UniPopup, UniPopupMessage }, data() { return { drawing: false, resultPrize: null } }, computed: { ...mapState('lottery', [ 'currentActivity', 'prizes', 'recentRecords', 'drawCount', 'maxDrawCount' ]), }, methods: { ...mapActions('lottery', ['fetchActivity', 'fetchPrizes']), ...mapMutations('lottery', ['SET_DRAW_COUNT', 'SET_RECENT_RECORDS']), formatDate(timestamp) { if (!timestamp) return '' const date = new Date(timestamp) return `${date.getMonth() + 1}月${date.getDate()}日` }, // 跳转到规则详情页 goToRules() { uni.navigateTo({ url: '/pages/rules/index' }) }, // 跳转到中奖记录页 goToRecords() { uni.navigateTo({ url: '/pages/records/index' }) }, // 处理弹窗关闭 handlePopupClose() { this.resultPrize = null }, async handleDraw() { if (this.drawing || this.drawCount >= this.maxDrawCount) return this.drawing = true try { // 开始转盘动画 if (this.$refs.wheelRef) { await this.$refs.wheelRef.startSpin() } // 随机选择奖品 const randomIndex = Math.floor(Math.random() * this.prizes.length) this.resultPrize = this.prizes[randomIndex] // 更新抽奖次数 this.SET_DRAW_COUNT(this.drawCount + 1) // 添加中奖记录 const newRecord = { user: "我", prize: this.resultPrize.name, time: this.getCurrentTime() } // 更新中奖记录(将新记录添加到最前面,并保留最近的10条) const updatedRecords = [newRecord, ...this.recentRecords].slice(0, 10) this.SET_RECENT_RECORDS(updatedRecords) // 显示中奖结果 this.$refs.resultPopup.open() } catch (error) { console.error("抽奖出错:", error) uni.showToast({ title: '抽奖失败', icon: 'none' }) } finally { this.drawing = false } }, // 获取当前时间 (HH:MM格式) getCurrentTime() { const now = new Date() return `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}` } }, async mounted() { // 获取活动数据 await this.fetchActivity() // 获取奖品数据 await this.fetchPrizes() // 如果中奖记录为空,初始化几条记录 if (!this.recentRecords || this.recentRecords.length === 0) { const records = [ { user: "张**", prize: "一等奖 iPhone 15", time: "10:25" }, { user: "李**", prize: "三等奖 京东卡", time: "10:22" }, { user: "王**", prize: "五等奖 优惠券", time: "10:20" } ] this.SET_RECENT_RECORDS(records) } } } </script> <style scoped> .index-page { padding: 20rpx; background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d); min-height: 100vh; color: #fff; } .activity-info { background: rgba(255, 255, 255, 0.1); border-radius: 16rpx; padding: 25rpx; margin-bottom: 30rpx; } .activity-name { font-size: 36rpx; font-weight: bold; margin-bottom: 15rpx; } .activity-time { font-size: 28rpx; opacity: 0.9; margin-bottom: 20rpx; } .activity-rules { display: flex; align-items: center; font-size: 24rpx; margin-bottom: 20rpx; padding: 15rpx; background: rgba(0, 0, 0, 0.1); border-radius: 10rpx; } .label { flex-shrink: 0; color: #FFD700; margin-right: 10rpx; } .rules-text { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .view-rules { flex-shrink: 0; color: #FFD700; font-size: 24rpx; margin-left: 15rpx; } .draw-count { padding: 15rpx; background: rgba(231, 76, 60, 0.2); border-radius: 10rpx; text-align: center; font-size: 28rpx; } .wheel-container { margin: 40rpx auto; position: relative; height: 600rpx; display: flex; justify-content: center; align-items: center; } .records-preview { background: rgba(255, 255, 255, 0.1); border-radius: 16rpx; padding: 20rpx; margin-top: 40rpx; } .records-preview .header { display: flex; justify-content: space-between; font-size: 32rpx; font-weight: bold; margin-bottom: 20rpx; } .view-all { font-size: 28rpx; color: #FFD700; } .record-item { display: flex; justify-content: space-between; padding: 20rpx 0; border-bottom: 1rpx solid rgba(255, 255, 255, 0.1); font-size: 28rpx; } .record-item .user { width: 25%; } .record-item .prize { width: 50%; text-align: center; } .record-item .time { width: 25%; text-align: right; opacity: 0.8; } </style>
07-08
<script setup lang="ts"> import { ref, computed, onMounted } from 'vue' interface Prize { id: number label: string color: string probability: number } const props = defineProps({ prizes: { type: Array as () => Prize[], required: true, validator: (value: Prize[]) => { const total = value.reduce((sum, prize) => sum + prize.probability, 0) return Math.abs(total - 1) < 0.01 } }, size: { type: Number, default: 400 }, spinDuration: { type: Number, default: 4 }, // 新增指针偏移角度属性 pointerOffset: { type: Number, default: -90 // 默认指针指向顶部(0°位置) } }) const emit = defineEmits(['spin-start', 'spin-end']) const isSpinning = ref(false) const rotateDeg = ref(0) const currentRotation = ref(0) const result = ref<Prize | null>(null) // 计算每个扇形的角度 const sectorAngle = computed(() => 360 / props.prizes.length) // 修正扇形样式计算 const getSectorStyle = (index: number) => { const startAngle = index * sectorAngle.value const endAngle = (index + 1) * sectorAngle.value // 计算扇形边界点 const startRad = (startAngle * Math.PI) / 180 const endRad = (endAngle * Math.PI) / 180 // 计算扇形的三个顶点 const center = '50% 50%' const startPoint = `${50 + 50 * Math.cos(startRad)}% ${50 + 50 * Math.sin(startRad)}%` const endPoint = `${50 + 50 * Math.cos(endRad)}% ${50 + 50 * Math.sin(endRad)}%` return { backgroundColor: props.prizes[index].color, clipPath: `polygon(${center}, ${startPoint}, ${endPoint})` } } // 修正文本样式计算 const getTextStyle = (index: number) => { // 计算扇形中心角度(弧度) const centerAngle = (index + 0.5) * sectorAngle.value const rad = (centerAngle * Math.PI) / 180 // 计算文本位置(距离中心的距离) const distance = props.size * 0.35 // 计算文本位置坐标(注意:CSS坐标系Y轴向下为正) const x = 50 + Math.cos(rad) * 35 // 35%的半径 const y = 50 + Math.sin(rad) * 35 // 35%的半径 return { left: `${x}%`, top: `${y}%`, transform: `translate(-50%, -50%) rotate(${centerAngle + 90}deg)` } } // 开始旋转 - 关键修正 const startSpin = () => { if (isSpinning.value) return const total = props.prizes.reduce((sum, prize) => sum + prize.probability, 0) if (Math.abs(total - 1) > 0.01) { alert('奖项概率总和必须为1') return } emit('spin-start') isSpinning.value = true result.value = null const random = Math.random() let cumulative = 0 let selectedIndex = 0 for (let i = 0; i < props.prizes.length; i++) { cumulative += props.prizes[i].probability if (random < cumulative) { selectedIndex = i break } } // 关键修正2:计算目标扇形中心到指针位置的角度差 const targetSectorCenter = (selectedIndex + 0.5) * sectorAngle.value const angleToPointer = targetSectorCenter - props.pointerOffset // 关键修正3:添加额外旋转圈数(5圈)并调整到指针位置 const extraRotations = 5 // 额外旋转圈数 const targetAngle = extraRotations * 360 - angleToPointer // 设置旋转角度(考虑当前旋转状态) rotateDeg.value = currentRotation.value + targetAngle currentRotation.value = rotateDeg.value setTimeout(() => { isSpinning.value = false result.value = props.prizes[selectedIndex] emit('spin-end', props.prizes[selectedIndex]) }, props.spinDuration * 1000) } // 根据旋转角度计算当前指针指向的扇形 const getCurrentPrizeIndex = () => { // 关键修正4:考虑指针偏移和旋转角度 const normalizedAngle = (currentRotation.value % 360 + 360) % 360 const pointerAngle = (normalizedAngle + props.pointerOffset + 360) % 360 return Math.floor(pointerAngle / sectorAngle.value) % props.prizes.length } const resetWheel = () => { rotateDeg.value = 0 currentRotation.value = 0 result.value = null } onMounted(() => { const total = props.prizes.reduce((sum, prize) => sum + prize.probability, 0) if (Math.abs(total - 1) > 0.01) { console.error('奖项概率总和必须为1,当前总和为:', total) } }) </script> <template> <div class="wheel-container"> <div class="wheel" :style="{ width: `${size}px`, height: `${size}px`, transform: `rotate(${rotateDeg}deg)`, transition: `transform ${spinDuration}s cubic-bezier(0.34, 1.56, 0.64, 1)` }" > <div v-for="(prize, index) in prizes" :key="prize.id" class="sector" :style="getSectorStyle(index)" > <div class="text" :style="getTextStyle(index)"> {{ prize.label }} </div> </div> <div class="center-circle"></div> </div> <div class="pointer"></div> <div class="controls"> <button class="spin-button" @click="startSpin" :disabled="isSpinning" > {{ isSpinning ? '旋转中...' : '开始旋转' }} </button> <button class="reset-button" @click="resetWheel">重置</button> </div> <div v-if="result" class="result"> <h3>恭喜您获得:</h3> <div class="prize-result"> <div class="prize-color" :style="{ backgroundColor: result.color }" ></div> <span>{{ result.label }}</span> </div> </div> </div> </template> <style scoped> .wheel-container { position: relative; display: flex; flex-direction: column; align-items: center; gap: 20px; padding: 20px; font-family: 'Arial', sans-serif; } .wheel { position: relative; border-radius: 50%; overflow: hidden; box-shadow: 0 0 20px rgba(0, 0, 0, 0.2); transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); } .sector { position: absolute; width: 100%; height: 100%; top: 0; left: 0; transform-origin: center center; } .text { position: absolute; color: white; font-weight: bold; font-size: 16px; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); white-space: nowrap; z-index: 2; /* 关键修正:确保文本居中定位 */ transform-origin: center center; transform: translate(-50%, -50%); text-align: center; /* 根据转盘大小调整字体大小 */ font-size: calc(12px + (0.02 * min(v-bind('size'), 400))); } .center-circle { position: absolute; top: 50%; left: 50%; width: 50px; height: 50px; background: white; border-radius: 50%; transform: translate(-50%, -50%); z-index: 3; box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); } .pointer { position: absolute; top: -20px; width: 30px; height: 50px; background: #e74c3c; clip-path: polygon(50% 100%, 0 0, 100% 0); z-index: 10; } .controls { display: flex; gap: 15px; margin-top: 20px; } .spin-button, .reset-button { padding: 10px 20px; border: none; border-radius: 30px; font-size: 16px; font-weight: bold; cursor: pointer; transition: all 0.3s; } .spin-button { background: linear-gradient(to right, #3498db, #2980b9); color: white; box-shadow: 0 4px 8px rgba(52, 152, 219, 0.4); } .spin-button:hover:not(:disabled) { background: linear-gradient(to right, #2980b9, #2573a7); transform: translateY(-2px); } .spin-button:disabled { background: #95a5a6; cursor: not-allowed; } .reset-button { background: #e0e0e0; color: #333; } .reset-button:hover { background: #d0d0d0; transform: translateY(-2px); } .result { margin-top: 20px; text-align: center; animation: fadeIn 0.5s; } .prize-result { display: flex; align-items: center; justify-content: center; gap: 10px; font-size: 24px; font-weight: bold; margin-top: 10px; } .prize-color { width: 30px; height: 30px; border-radius: 50%; border: 2px solid #ddd; } @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } </style> 此代码只有每次重置后,再去执行转盘第一次是准的。如何调整每次执行都是准的呢
08-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值